Tworzę aplikację na iOS i używam Storyboard z włączoną funkcją AutoLayout. Jeden z moich kontrolerów widoku ma zestaw 4 przycisków iw pewnych okolicznościach chciałbym, aby pierwszy z nich zniknął.
Jeśli setHidden:TRUE
użyję tej metody, przycisk UIButton stanie się niewidoczny, ale nadal oczywiście zajmie miejsce w widoku, a wynikiem jest „dziura”, której nie byłem w stanie wypełnić, powodując, że pozostały przycisk UIButton unosi się w kierunku górnej części widoku głównego.
W Androidzie użyłbym po prostu View.GONE
zamiast tego View.INVISIBLE
, ale w iOS utknąłem z tym zachowaniem i nie chcę wierzyć, że jedynym rozwiązaniem jest ręczne (tak mam na myśli programowo) przesunięcie pozostałych elementów na górę.
Pomyślałem, że byłbym w stanie to zrobić, ustawiając jakieś ograniczenie, aby wszystko było tak automatyczne, jak w Androidzie, ale nie miałem szczęścia.
Czy ktoś może wskazać mi właściwy kierunek, zanim wyłączę Autolayout?
Używam IB, ale nie przeszkadza mi też programowanie.
AKTUALIZACJA:
Ustawienie wysokości komponentu na 0 też nie pomaga.
Próbowałem czegoś takiego:
UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;
źródło
Odpowiedzi:
Dodanie ograniczenia (NSLayoutAttributeHeight), które ustawia wysokość widoku na 0, zadziałało dla mnie:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];
źródło
self.view.addConstraint(NSLayoutConstraint(item: self.captchaView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0))
Unable to simultaneously satisfy constraints
. podczas gdy miałem już ograniczenia dla widoku. Rozwiązuję to przez stackoverflow.com/a/38625419/1270901Wszystkie odpowiedzi na te pytania są nieskuteczne. Najlepszym sposobem na wyrównanie systemu Android setVisibility: Gone w systemie iOS jest
StackView
wybranie komponentów, a następnie w edytorze, osadzenie w widoku stosu,połącz nowy widok stosu z IBOutlet, a następnie:
ukryty:
UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0]; firstView.hidden = YES;
widoczność:
UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0]; firstView.hidden = NO;
tak jak w przypadku widoku stosu, wszystkie ograniczenia zostaną zachowane!
Dokument
źródło
dodaj ograniczenie wysokości do widoku w następujący sposób:
następnie utwórz ujście dla ograniczenia wysokości w swoim pliku viewController w następujący sposób:
a następnie w metodzie viewDidLoad zmień wysokość ograniczenia na 0 w następujący sposób:
override func viewDidLoad() { super.viewDidLoad() nsLcButtonHeight.constant = 0 }
źródło
Aby uzyskać funkcjonalność Androids.GONE na iOS, należy użyć UIStackView. Następnie ukryj dziecko według pozycji. ( Dokumentacja jabłek )
SWIFT 4:
let firstView = cell.rootStackView.arrangedSubviews[0] firstView.isHidden = true // first view gone
To przykład komórki tabeli, po prostu włóż oba wnętrze
Stack view
i zdobądź przedmiot dlaGONE
dziecka.źródło
Możesz zgrupować swoje widoki w widoku stosu. Następnie, gdy ukryjesz określony widok, pozostałe widoki zostaną automatycznie przesunięte, aby wypełnić przestrzeń.
Możesz sprawdzić dokumentację Apple w widokach stosu: https://developer.apple.com/reference/uikit/uistackview
lub samouczki online, takie jak: https://www.appcoda.com/stack-views-intro/
źródło
1) Jeśli twoje przyciski są ustawione pionowo, musisz ustawić na
height
0, aw przypadku przycisków umieszczonych poziomo spróbuj ustawićwidth
na 0 lub możesz ustawić oba na 0.LUB
2) można spróbować tego podejścia, które ustawia
button2
się na szczyciebutton1
:- (void)viewDidLoad { [super viewDidLoad]; UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button1 setTitle:@"hello" forState:UIControlStateNormal]; UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button2 setTitle:@"world" forState:UIControlStateNormal]; [button1 sizeToFit]; [button2 sizeToFit]; [button2 setFrame:CGRectMake(button1.frame.origin.x, button1.frame.origin.y, button2.frame.size.width, button2.frame.size.height)]; [self.view addSubview:button1]; [self.view addSubview:button2]; }
źródło
https://github.com/tazihosniomar/LayoutManager
mam nadzieję, że ci to pomoże.
źródło
To pytanie jest dość stare, ale najbardziej ukrytą rzeczą, którą znalazłem, jest ustawienie dodatkowych ograniczeń (aby widoki wokół widoku „nie ma” wiedzą, co zrobić, gdy go brakuje)
A which you want to be A | after setting B to gone | B C | C
bConstraints
. Zrób to przez:bConstraints
.@IBOutlet var bConstraints: [NSLayoutConstraint]!
w Twoim ViewControllerNastępnie ukryj B.
B.hidden = true NSLayoutConstraint.deactivateConstraints(bConstraints)
Aby odkryć
B.hidden = false NSLayoutConstraint.activateConstraints(bConstraints)
Oczywiście im więcej i więcej masz widoków, tym bardziej jest to złożone, ponieważ potrzebujesz dodatkowych ograniczeń z każdego widoku
źródło
Outlet
naOutlet Collection
. Aby uzyskać dodatkowe ograniczenia, przeciągnij klawisz Ctrl bezpośrednio do nazwy zmiennej. Sceenshoty mogę przesłać później (za ~ 8 godzin)Jak wykazały moje badania, nawet AutoLayout nie może Ci pomóc. Musisz ręcznie zastąpić widoki, na które ma wpływ opcjonalny pokazany komponent (w moim przypadku wszystkie widoki do dołu opcjonalnego widoku, ale jestem pewien, że możesz to dostosować, aby obsługiwać wszystkie przyciski po prawej stronie twojego opcjonalnego przycisku ):
- (IBAction)toggleOptionalView:(id)sender { if (!_expanded) { self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, _optionalHeight); self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y+_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height); _expanded = YES; } else { self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, 0); self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y-_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height); _expanded = NO; } }
Zaleca się, aby nie zakodować na stałe wysokości / szerokości opcjonalnych komponentów, w przeciwnym razie twój kod zepsuje się za każdym razem, gdy edytujesz XIB / Storyboard. Mam pole float _optionalHeight, które ustawiłem w viewDidLoad, więc jest zawsze aktualne.
źródło
Możesz także wyczyścić stronę lub przynajmniej niektóre komórki strony i przedefiniować całość. Jest szybki i działa dobrze. Nie napisałem kodu, ale znalazłem go w tym istniejącym projekcie, nad którym pracuję. Twórz
ManagementTableSection
i twórzManagementTableCell
zajęcia, aby zarządzać tym wszystkim. Przepraszam, nie mogę podać lepiej zdefiniowanego kodu.źródło
Opierając się na odpowiedzi udzielonej przez Deniz, oto rozwiązanie wykorzystujące ograniczenia w Swift
Na przykład: jeśli masz 3 widoki, A_view B_view i C_view wyrównane w pionie w tej kolejności i chcesz „Ukryć” B, a także dostosować różnicę, dodaj ograniczenie
B_view.removeFromSuperView() var constr = NSLayoutConstraint(item: C_view, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: A_view, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 20) view.addConstraint(constr)
stała to (w tym przypadku) wielkość odstępu w pionie między C_view i A_view
źródło
Dodałem nową właściwość do niestandardowej implementacji UIView o nazwie „visible”, która po ustawieniu wartości false dodaje ograniczenie powodujące zwinięcie widoku (dodałem tylko ograniczenie szerokości, ponieważ moja lista jest pozioma, ale najlepszym sposobem może być dodanie również ograniczenie wysokości równe 0).
var visible:Bool = true{ didSet{ if(visible){ clipsToBounds = false; removeConstraint(hideConstraint!) }else{ clipsToBounds = true addConstraint(hideConstraint!) } } }
Musisz zainicjować ograniczenie zerowej szerokości w widoku i dodać je jako pole:
private var hideConstraint:NSLayoutConstraint? func someInitFunction(){ hideConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0) ... }
źródło
setHidden: TRUE / FALSE jest najbliższym odpowiednikiem Android View.GONE / VISIBLE.
Widok niekoniecznie zajmuje miejsce, jeśli nie jest widoczny!
Stworzyłem ComboBox-Alike z ListView leżącym na wierzchu innych widoków. Jestem widoczny tylko podczas zaznaczania:
źródło