Jak korzystać z automatycznego układu, aby przenosić inne widoki, gdy widok jest ukryty?


333

Zaprojektowałem moją niestandardową komórkę w IB, podklasowałem ją i połączyłem swoje gniazdka z moją niestandardową klasą. Mam trzy podstrony w treści komórki, które są: UIView (cdView) i dwie etykiety (titleLabel i emailLabel). W zależności od danych dostępnych dla każdego wiersza, czasami chcę mieć UIView i dwie etykiety wyświetlane w mojej komórce, a czasem tylko dwie etykiety. Staram się w ten sposób ustawić ograniczenia, jeśli ustawię właściwość UIView na ukrytą lub usunę ją z podglądu, dwie etykiety zostaną przesunięte w lewo. Próbowałem ustawić wiodące ograniczenie UIView na Superview (zawartość komórki) dla 10px i UILabels wiodące ograniczenia dla 10 px do następnego widoku (UIView). Później w moim kodzie

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];

if ([record.imageURL is equalToString:@""]) {
     cell.cdView.hidden = YES;
}

Chowam swoją komórkę. CdView i chciałbym, aby etykiety przesunęły się w lewo, jednak pozostają one w tej samej pozycji w komórce. Próbowałem usunąć cell.cdView z podglądu, ale to też nie działało. Załączam obraz, aby wyjaśnić, o co mi chodzi.

komórka

Wiem, jak to zrobić programowo i nie szukam tego rozwiązania. Chcę ustawić ograniczenia w IB i oczekuję, że moje widoki podrzędne będą się dynamicznie przemieszczać, jeśli inne widoki zostaną usunięte lub ukryte. Czy można to zrobić w IB z automatycznym układem?

.....

Zmień czas działania wartości ograniczeń - sprawdź tę odpowiedź
Kampai

W tym konkretnym przypadku można również użyć UIStackView. kiedy ukryjesz płytę, etykiety zajmą ich miejsce
Marco Pappalardo,

Odpowiedzi:


373

Jest to możliwe, ale będziesz musiał wykonać trochę dodatkowej pracy. Najpierw trzeba usunąć kilka koncepcyjnych rzeczy:

  • Ukryte widoki, mimo że nie rysują, nadal uczestniczą w Automatycznym układzie i zwykle zachowują swoje ramki , pozostawiając inne powiązane widoki na swoich miejscach.
  • Podczas usuwania widoku z jego podglądu wszystkie powiązane ograniczenia są również usuwane z tej hierarchii widoków.

W twoim przypadku prawdopodobnie oznacza to:

  • Jeśli ustawisz ukrywanie lewego widoku, etykiety pozostaną na miejscu, ponieważ ten lewy widok nadal zajmuje miejsce (nawet jeśli nie jest widoczny).
  • Jeśli usuniesz lewy widok, etykiety prawdopodobnie zostaną niejednoznacznie ograniczone, ponieważ nie masz już ograniczeń dla lewej krawędzi etykiet.

To, co musisz zrobić, to rozsądnie przeciążyć swoje etykiety. Pozostaw istniejące ograniczenia (przestrzeń 10 punktów do drugiego widoku) w spokoju, ale dodaj kolejne ograniczenie: ustaw lewą krawędź etykiet 10 punktów od lewej krawędzi ich podglądu z niepotrzebnym priorytetem (domyślnie wysoki priorytet prawdopodobnie będzie działał dobrze).

Następnie, jeśli chcesz, aby przesunęli się w lewo, całkowicie usuń lewy widok. Obowiązkowe ograniczenie 10 punktów do lewego widoku zniknie wraz z widokiem, którego dotyczy, a Ty pozostaniesz z ograniczeniem o wysokim priorytecie, że etykiety będą oddalone o 10 punktów od ich podglądu. Przy następnym przejściu do układu powinno to spowodować ich rozszerzenie w lewo, dopóki nie wypełnią szerokości podglądu, ale w celu uzyskania odstępów wokół krawędzi.

Jedno ważne zastrzeżenie: jeśli kiedykolwiek chcesz przywrócić lewy widok na obrazie, musisz nie tylko dodać go z powrotem do hierarchii widoków, ale także przywrócić wszystkie jego ograniczenia w tym samym czasie. Oznacza to, że potrzebujesz sposobu na przywrócenie 10-punktowego ograniczenia odległości między widokiem i jego etykietami, ilekroć ten widok zostanie ponownie wyświetlony.


8
Chociaż ta odpowiedź na pewno zadziała, IMO, nadmierne ograniczenie obsługi różnych przypadków użycia wydaje się być zapachem kodu - szczególnie, że trzeba będzie ponownie ustalić wszystkie ograniczenia dla usuniętych widoków, które chcesz ponownie wyświetlić.
memmons,

Moim zdaniem nie jest to dobra droga. Zamiast tego powinieneś użyć ograniczenia szerokości / wysokości dla widoku, który chcesz ukryć.
ullstrm

26
Z szacunkiem się nie zgadzam. Jeśli (na przykład) ustawisz szerokość widoku na 0, napotkasz dwa problemy. Po pierwsze, masz teraz podwójne odstępy między widokiem a widokiem widocznym: |-(space)-[hidden(0)]-(space)-[visible]jest efektywny |-(2*space)-[visible]. Po drugie, widok ten może zacząć rzucać naruszenia ograniczeń w zależności od własnego poddrzewa i ograniczeń widoku - nie możesz zagwarantować, że możesz dowolnie ograniczyć widok o szerokości 0 i sprawić, by nadal działał.
Tim

1
Jeśli używasz widoku o wewnętrznej zawartości, odpowiedź Tima wydaje się być jedyną w swoim rodzaju drogą.
Balkoth

Dziękuję Tim. Ustawiam ograniczenie 0 z wyższym priorytetem, aby uniknąć niezgodności ograniczeń, ale teraz zdaję sobie sprawę, że jest problem z podwójnymi odstępami. Nie miałem tego problemu, ponieważ nigdy nie pokazuję dwóch widoków razem (mój przypadek |-[otherViews]-[eitherThis][orThis]-|:), ale w końcu napotkałem ten problem.
Ferran Maylinch,

207

Dodawanie lub usuwanie ograniczeń w czasie wykonywania jest operacją ciężką, która może wpływać na wydajność. Istnieje jednak prostsza alternatywa.

Dla widoku, który chcesz ukryć, ustaw ograniczenie szerokości. Ogranicz inne widoki z wiodącą poziomą przerwą do tego widoku.

Aby ukryć, zaktualizuj .constantograniczenie szerokości do 0.f. Pozostałe widoki zostaną automatycznie przesunięte w lewo, aby przyjąć pozycję.

Zobacz moją inną odpowiedź tutaj, aby uzyskać więcej informacji:

Jak zmienić ograniczenia etykiety podczas działania?


29
Jedynym problemem związanym z tym rozwiązaniem jest to, że margines po lewej stronie będzie podwójny z tego, co prawdopodobnie chcesz, więc zaktualizowałbym również jedno z tych ograniczeń, ale nawet wtedy myślę, że jest to mniej pracy niż usunięcie podview.
José Manuel Sánchez

2
@ skinsfan00atg Jeśli używasz widoku z wewnętrzną wielkością zawartości, nie możesz użyć tego rozwiązania.
Balkoth

@ Baloth dlaczego nie? Możesz po prostu zmniejszyć priorytet przytulania zawartości
Max MacLeod

2
@MaxMacLeod Jeśli zmniejszysz priorytet przytulania treści, nie użyjesz wewnętrznego rozmiaru zawartości, użyjesz rozmiaru wskazanego przez ograniczenie.
balkoth

2
@MaxMacLeod Ok, rozumiem co masz na myśli. Musisz ustawić priorytet odporności na kompresję na 0 (nie przytulanie zawartości) w kodzie, jeśli chcesz ukryć widok, a gdy chcesz ponownie pokazać, przywróć tę wartość. Oprócz tego należy dodać ograniczenie w narzędziu do tworzenia interfejsów, aby ustawić rozmiar widoku na 0. Nie ma potrzeby dotykania tego ograniczenia w kodzie.
balkoth

87

Dla tych, którzy wspierają iOS 8+ tylko, jest to nowy obiekt Boolean aktywny . Pomoże to dynamicznie włączać tylko potrzebne ograniczenia

Gniazdo PS Constraint musi być mocne , a nie słabe

Przykład:

@IBOutlet weak var optionalView: UIView!
@IBOutlet var viewIsVisibleConstraint: NSLayoutConstraint!
@IBOutlet var viewIsHiddenConstraint: NSLayoutConstraint!

func showView() {
    optionalView.isHidden = false
    viewIsVisibleConstraint.isActive = true
    viewIsHiddenConstraint.isActive = false
}

func hideView() {
    optionalView.isHidden = true
    viewIsVisibleConstraint.isActive = false
    viewIsHiddenConstraint.isActive = true
}

Ponadto, aby naprawić błąd w serii ujęć, musisz odznaczyć Installedpole wyboru dla jednego z tych ograniczeń.

UIStackView (iOS 9+)
Jeszcze jedną opcją jest zawinięcie swoich widoków UIStackView. Po ukryciu widoku UIStackViewautomatycznie zaktualizuje układ


aktywne częściowo działa. Ale jeśli użyję go w komórce wielokrotnego użytku, od aktywacji do dezaktywacji, działa, ale nie do dezaktywacji w celu aktywacji. Jakieś pomysły? A może mógłbyś podać przykład?
Aoke Li

10
Dzieje się tak, ponieważ dezaktywowane ograniczenie nie jest ładowane ani zwalniane. Ograniczenie powinno być silne, a nie słabe
Silmaril,

Gdzie możemy znaleźć tę „aktywną” właściwość?
Lakshmi Reddy,


Wygląda na to, że nadmierne ograniczenie + ustawienie ograniczenia może być najbardziej rozsądną odpowiedzią.
Ting Yi Shih,

68

UIStackViewautomatycznie hiddenzmienia swoje widoki, gdy właściwość jest zmieniana w dowolnym z jego widoków podrzędnych (iOS 9+).

UIView.animateWithDuration(1.0) { () -> Void in
   self.mySubview.hidden = !self.mySubview.hidden
}

Przejdź do 11:48 w tym wideo WWDC, aby zobaczyć demo:

Tajemnice automatycznego układu, część 1


Ukryłem widok zagnieżdżonego stosu i cały widok zawierający stos zniknął.
Ian Warburton

5
To powinna być zaakceptowana odpowiedź. Zgodnie z zaleceniami Apple z wwdc 2015 na temat projektowania konstruktorów interfejsów.
thibaut noah

@thibautnoah A co z obsługą iOS 8?
bagaż

5
@bagage O ile nie jesteś Facebookiem lub Google, możesz to upuścić. Z zasięgiem od iOS 9 będziesz obsługiwać ponad 90% urządzeń, więcej niż wystarczająco. Wspieranie poniżej utrudni twój proces rozwoju i uniemożliwi korzystanie z najnowszych funkcji imo
thibaut noah

16

Mój projekt używa niestandardowej @IBDesignablepodklasy UILabel(aby zapewnić spójność kolorów, czcionek, wypustek itp.) I zaimplementowałem coś takiego:

override func intrinsicContentSize() -> CGSize {
    if hidden {
        return CGSizeZero
    } else {
        return super.intrinsicContentSize()
    }
}

Dzięki temu podklasa etykiet może brać udział w automatycznym układzie, ale nie zajmuje miejsca, gdy jest ukryta.


13

Dla Googlersów: na odpowiedzi Maxa, aby rozwiązać problem dopełniania, który wielu zauważyło, po prostu zwiększyłem wysokość etykiety i użyłem tej wysokości jako separatora zamiast rzeczywistego wypełnienia. Ten pomysł można rozszerzyć na dowolny scenariusz z widokami zawierającymi.

Oto prosty przykład:

Zrzut ekranu IB

W takim przypadku odwzorowuję wysokość etykiety autora na odpowiednią IBOutlet:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

a kiedy ustawię wysokość ograniczenia na 0.0f, zachowujemy „wypełnienie”, ponieważ pozwala na to wysokość przycisku Play .


Dla tych, którzy są nowe NSLayoutConstraintwierzę, że chcesz zaktualizować constantwłaściwość twoich authorLabelHeight.
Kyle

8

połącz ograniczenie między uiview a etykietami jako IBOutlet i ustaw element członkowski priorytet na mniejszą wartość, gdy ustawiony ukryty = TAK


3
Po ustaleniu priorytetu NSLayoutConstraint nie można dostosować; musisz usunąć i odczytać nowe ograniczenie z innym priorytetem.
Tim

7
Mam tę metodę do pracy. Mam skrzynkę z etykietą i przyciskiem, w której muszę ukryć przycisk i rozwinąć etykietę. Mam dwa ograniczenia, jeden początkowo z priorytetem 751, a drugi z 750. Następnie, gdy ukrywam przycisk, zmieniam priorytety i długość etykiety rośnie. Należy zauważyć, że jeśli spróbujesz ustawić wyższy priorytet 1000, pojawi się błąd „Mutowanie priorytetu z wymaganego na nie na zainstalowanym ograniczeniu (lub odwrotnie) nie jest obsługiwane.”. Więc nie rób i wydajesz się być w porządku. Xcode 5.1 / viewDidLoad.
John Bushnell

8

Skończyło się na stworzeniu 2 xibów. Jeden z lewym widokiem, a drugi bez niego. Zarejestrowałem się zarówno w kontrolerze, a następnie zdecydowałem, którego użyć podczas cellForRowAtIndexPath.

Używają tej samej klasy UITableViewCell. Minusem jest to, że istnieje pewna duplikacja zawartości między xib, ale te komórki są dość podstawowe. Plusem jest to, że nie mam dużo kodu do ręcznego zarządzania usuwaniem widoku, aktualizowaniem ograniczeń itp.

Ogólnie rzecz biorąc, jest to prawdopodobnie lepsze rozwiązanie, ponieważ są to technicznie różne układy i dlatego powinny mieć różne xib.

[self.table registerNib:[UINib nibWithNibName:@"TrackCell" bundle:nil] forCellReuseIdentifier:@"TrackCell"];
[self.table registerNib:[UINib nibWithNibName:@"TrackCellNoImage" bundle:nil] forCellReuseIdentifier:@"TrackCellNoImage"];

TrackCell *cell = [tableView dequeueReusableCellWithIdentifier:(appDelegate.showImages ? @"TrackCell" : @"TrackCellNoImage") forIndexPath:indexPath];

7

W takim przypadku odwzorowuję wysokość etykiety autora na odpowiedni IBOutlet:

@property (retain, nonatomic) IBOutlet NSLayoutConstraint* authorLabelHeight;

a kiedy ustawię wysokość ograniczenia na 0.0f, zachowujemy „padding”, ponieważ pozwala na to wysokość przycisku Play.

cell.authorLabelHeight.constant = 0;

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj


6

Użyj dwóch UIStackView poziomego i pionowego, gdy ukryty jest widok częściowy stosu, inne widoki częściowe stosu zostaną przeniesione, użyj opcji Dystrybucja -> Wypełnij proporcjonalnie do stosu pionowego dwoma etykietami UIL i należy ustawić ograniczenia szerokości i wysokości dla pierwszego UIViewwprowadź opis zdjęcia tutaj


2

Spróbuj, zaimplementowałem poniższy kod,

Mam jeden widok na ViewController w dodanych trzech innych widokach. Gdy jakikolwiek widok jest ukryty, pozostałe dwa zostaną przeniesione, wykonaj poniższe kroki. ,

1. plikViewController.h

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UIView *viewOne;
@property (strong, nonatomic) IBOutlet UIView *viewTwo;
@property (strong, nonatomic) IBOutlet UIView *viewThree;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewOneWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewTwoWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewThreeWidth;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *viewBottomWidth;
@end

2.ViewController.m

 #import "ViewController.h"
 @interface ViewController ()
{
  CGFloat viewOneWidthConstant;
  CGFloat viewTwoWidthConstant;
  CGFloat viewThreeWidthConstant;
  CGFloat viewBottomWidthConstant;
}
@end

@implementation ViewController
@synthesize viewOne, viewTwo, viewThree;

- (void)viewDidLoad {
  [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a 
  nib.

  /*
   0  0   0
   0  0   1
   0  1   0
   0  1   1
   1  0   0
   1  0   1
   1  1   0
   1  1   1
   */

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:NO];
  //    [viewTwo setHidden:YES];
  //    [viewThree setHidden:YES];


  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:NO];

  //    [viewOne setHidden:YES];
  //    [viewTwo setHidden:NO];
  //    [viewThree setHidden:YES];

 //    [viewOne setHidden:YES];
 //    [viewTwo setHidden:YES];
 //    [viewThree setHidden:NO];

//    [viewOne setHidden:YES];
//    [viewTwo setHidden:YES];
//    [viewThree setHidden:YES];

 [self hideShowBottomBar];
  }

- (void)hideShowBottomBar
{
  BOOL isOne = !viewOne.isHidden;
  BOOL isTwo = !viewTwo.isHidden;
  BOOL isThree = !viewThree.isHidden;

  viewOneWidthConstant = _viewOneWidth.constant;
  viewTwoWidthConstant = _viewTwoWidth.constant;
  viewThreeWidthConstant = _viewThreeWidth.constant;
  viewBottomWidthConstant = _viewBottomWidth.constant;

   if (isOne && isTwo && isThree) {
    // 0    0   0
    _viewOneWidth.constant = viewBottomWidthConstant / 3;
    _viewTwoWidth.constant = viewBottomWidthConstant / 3;
    _viewThreeWidth.constant = viewBottomWidthConstant / 3;
    }
    else if (isOne && isTwo && !isThree) {
     // 0    0   1
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = 0;
    }
   else if (isOne && !isTwo && isThree) {
    // 0    1   0
    _viewOneWidth.constant = viewBottomWidthConstant / 2;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
    }
    else if (isOne && !isTwo && !isThree) {
    // 0    1   1
    _viewOneWidth.constant = viewBottomWidthConstant;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && isTwo && isThree) {
    // 1    0   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant / 2;
    _viewThreeWidth.constant = viewBottomWidthConstant / 2;
   }
   else if (!isOne && isTwo && !isThree) {
    // 1    0   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = viewBottomWidthConstant;
    _viewThreeWidth.constant = 0;
   }
   else if (!isOne && !isTwo && isThree) {
    // 1    1   0
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = viewBottomWidthConstant;
   }
   else if (isOne && isTwo && isThree) {
    // 1    1   1
    _viewOneWidth.constant = 0;
    _viewTwoWidth.constant = 0;
    _viewThreeWidth.constant = 0;
   }
  }

 - (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
 // Dispose of any resources that can be recreated.
 }
 @end

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

Mam nadzieję, że ta logika komuś pomoże.


1

W moim przypadku ustawiłem stałą ograniczenia wysokości na, 0.0fa także ustawiłem hiddenwłaściwość na YES.

Aby ponownie wyświetlić widok (z widokami podrzędnymi), zrobiłem coś przeciwnego: ustawiłem stałą wysokości na wartość niezerową i ustawiłem hiddenwłaściwość na NO.


1

Użyję poziomego widoku stosu. Może usunąć ramkę, gdy widok podrzędny jest ukryty.

Na poniższym obrazku czerwony widok jest faktycznym kontenerem dla twojej zawartości i ma 10pt końcowe miejsce na pomarańczowy superview (ShowHideView), a następnie po prostu podłącz ShowHideView do IBOutlet i pokaż / ukryj / usuń programowo.

  1. To wtedy widok jest widoczny / zainstalowany.

widok jest widoczny

  1. Dzieje się tak, gdy widok jest ukryty / niezainstalowany.

widok jest ukryty / usunięty


1

To moje kolejne rozwiązanie wykorzystujące ograniczenie pierwszeństwa. Ideą jest ustawienie szerokości na 0.

  1. utwórz widok kontenera (pomarańczowy) i ustaw szerokość. wprowadź opis zdjęcia tutaj

  2. utwórz widok zawartości (czerwony) i ustaw odstęp 10pt na podgląd (pomarańczowy). Zwróć uwagę na końcowe ograniczenia miejsca, istnieją 2 końcowe ograniczenia o różnym priorytecie. Niski (= 10) i wysoki (<= 10). Jest to ważne, aby uniknąć dwuznaczności. wprowadź opis zdjęcia tutaj

  3. Ustaw szerokość widoku pomarańczowego na 0, aby ukryć widok. wprowadź opis zdjęcia tutaj


0

Jak sugeruje no_scene, zdecydowanie możesz to zrobić, zmieniając priorytet ograniczenia w czasie wykonywania. Było to dla mnie znacznie łatwiejsze, ponieważ miałem więcej niż jeden widok blokujący, który należałoby usunąć.

Oto fragment kodu przy użyciu ReactiveCocoa:

RACSignal* isViewOneHiddenSignal = RACObserve(self.viewModel, isViewOneHidden);
RACSignal* isViewTwoHiddenSignal = RACObserve(self.viewModel, isViewTwoHidden);
RACSignal* isViewThreeHiddenSignal = RACObserve(self.viewModel, isViewThreeHidden);
RAC(self.viewOne, hidden) = isViewOneHiddenSignal;
RAC(self.viewTwo, hidden) = isViewTwoHiddenSignal;
RAC(self.viewThree, hidden) = isViewThreeHiddenSignal;

RAC(self.viewFourBottomConstraint, priority) = [[[[RACSignal
    combineLatest:@[isViewOneHiddenSignal,
                    isViewTwoHiddenSignal,
                    isViewThreeHiddenSignal]]
    and]
    distinctUntilChanged]
    map:^id(NSNumber* allAreHidden) {
        return [allAreHidden boolValue] ? @(780) : @(UILayoutPriorityDefaultHigh);
    }];

RACSignal* updateFramesSignal = [RACObserve(self.viewFourBottomConstraint, priority) distinctUntilChanged];
[updateFramesSignal
    subscribeNext:^(id x) {
        @strongify(self);
        [self.view setNeedsUpdateConstraints];
        [UIView animateWithDuration:0.3 animations:^{
            [self.view layoutIfNeeded];
        }];
    }];


0

Oto jak ponownie wyrównaj moje uiviews, aby uzyskać twoje rozwiązanie:

  1. Przeciągnij upuść jeden UIImageView i umieść go w lewo.
  2. Przeciągnij upuść jeden UIView i umieść go po prawej stronie UIImageView.
  3. Przeciągnij upuść dwa etykiety UIL wewnątrz tego UIView, którego wiodące i końcowe ograniczenia są zerowe.
  4. Ustaw wiodące ograniczenie UIView zawierające 2 etykiety do podglądu zamiast UIImagView.
  5. JEŚLI UIImageView jest ukryty, ustaw wiodącą stałą ograniczenia na 10 px, aby móc go nadzorować. ELSE, ustaw wiodącą stałą wiązania na 10 px + UIImageView.width + 10 px.

Stworzyłem własną zasadę kciuka. Ilekroć musisz ukryć / pokazać dowolny podgląd uiview, na którego ograniczenia może mieć wpływ, dodaj wszystkie dotknięte / zależne widoki podrzędne w uiview i aktualizuj jego stałe ograniczenie wiodące / końcowe / górne / dolne.


0

To stare pytanie, ale wciąż mam nadzieję, że to pomoże. Pochodzący z Androida, na tej platformie masz przydatną metodę isVisibleukrywania go przed widokiem, ale nie bierzesz także pod uwagę ramki, gdy autoukład rysuje widok.

Używając rozszerzenia i rozszerzenia „uiview”, możesz wykonać podobną funkcję w systemie iOS (nie jestem pewien, dlaczego nie ma go już w UIKit) tutaj implementacja w swift 3:

    func isVisible(_ isVisible: Bool) {
        self.isHidden = !isVisible
        self.translatesAutoresizingMaskIntoConstraints = isVisible
        if isVisible { //if visible we remove the hight constraint 
            if let constraint = (self.constraints.filter{$0.firstAttribute == .height}.first){
                self.removeConstraint(constraint)
            }
        } else { //if not visible we add a constraint to force the view to have a hight set to 0
            let height = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal , toItem: nil, attribute: .notAnAttribute, multiplier: 0, constant: 0)
            self.addConstraint(height)
        }
        self.layoutIfNeeded()
    }

0

właściwym sposobem na to jest wyłączenie ograniczeń za pomocą isActive = false. zauważ jednak, że dezaktywacja ograniczenia usuwa je i zwalnia, więc musisz mieć dla nich mocne gniazda.


0

Najłatwiejszym rozwiązaniem jest użycie UIStackView (poziomo). Dodaj do widoku stosu: pierwszy widok i drugi widok z etykietami. Następnie ustaw właściwość isHidden pierwszego widoku na false. Wszystkie ograniczenia zostaną obliczone i zaktualizowane automatycznie.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.