2016-09-27 63 views
6

Dodaję z widoku Xib do mojego ViewController. Następnie Kładę swoje ograniczenia faktycznie dopasować goOgraniczenia końcowe i końcowe w Swift programowo (NSLayoutConstraints)

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    ... 
    ... 
    view!.addSubview(gamePreview) 
    gamePreview.translatesAutoresizingMaskIntoConstraints = false 
    if #available(iOS 9.0, *) { 
     // Pin the leading edge of myView to the margin's leading edge 
     gamePreview.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true 
     //Pin the trailing edge of myView to the margin's trailing edge 
     gamePreview.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true 

    } else { 
     // Fallback on earlier versions 
     view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .TrailingMargin, relatedBy: .Equal, toItem: view, attribute: .TrailingMargin, multiplier: 1, constant: 0)) 

     view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .LeadingMargin, relatedBy: .Equal, toItem: view, attribute: .LeadingMargin, multiplier: 1, constant: 0)) 
    } 
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0)) 
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131)) 
} 

co usiłuję zrobić: Aby właściwie dopasować mój pogląd ograniczając go do góry, prowadząc, ciągnąc do widoku ViewController, a z ustalonej wysokości. Widok, który dodaję do widoku głównego, ma własny widok przezroczystego tła, więc nie ma potrzeby marginesu (widok ma być wielkością urządzenia, więc).

Umieściłem dwie pary linii, które powinny być równe (w moich próbach), z jeśli, ponieważ pierwsze 2 linie w rzeczywistości są dostępne tylko w iOS9>, podczas gdy ja próbuję zrób to samo w instrukcji else dla każdego urządzenia (począwszy od iOS 8).

To co mam:

iOS9 + w lewo, systemów iOS 8 + po prawej stronie. Przezroczyste tło zostało pomalowane na czerwono, aby zobaczyć, co się dzieje (nie przeszkadza w różnej wysokości w obrazach, są równe wysokości w aplikacji, zamiast patrzeć na dodanych marginesy lewy i prawy)

Próbowałem też AutoLayoutDSL-Swift, ale nie pomaga, nie jestem ekspertem, ale każda próba tylko pogorszyła sprawę.

Jak mogę napisać te ograniczenia za pomocą klasycznych metod NSLayoutConstraints i jak mogę napisać wszystko w lepszy sposób za pomocą frameworka takiego jak AutoLayoutDSL lub jego rozwidlenia? (Lub alternatywną, choć teraz głównie Martwię na oficjalnych libs)

+2

W swoich wstępnych iOS kod 9 użyłeś '' trailingMargin' leadingMargin' i marże, więc otrzymujesz. Użyj 'leading' i' trailing' zamiast – Paulw11

+0

Ponadto, jeśli wprowadzisz tę zmianę, ten sam kod będzie działał we wszystkich wersjach, iOS 8 i nowsze – Paulw11

+0

Działa! Czy mógłbyś także powiedzieć mi, jak użyć AutoLayoutDSL-Swift dla najwyższej kotwicy, specjalnie dla paska nawigacyjnego ... Próbowałem 'view => gamePreview.top == view.top', aby osiągnąć to, co dostaję na drugi koniec ograniczenie, ale widok przechodzi pod nawigacjąBar ... Pomógłbym zredukować cały ten nadęty kod do linii podzielonej przez 4. Próbowałem dodać przesunięcie z sumą 'self.navigationController !.navigationBar.height', ale daje błąd kompilacji, podczas gdy działa na numerowanie rzeczywistej liczby (np. 30). – BlackBox

Odpowiedz

13

Musisz użyć leading i trailing atrybuty, a nie leadingMargin i trailingMargin atrybuty:

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    ... 
    ... 
    view!.addSubview(gamePreview) 
    gamePreview.translatesAutoresizingMaskIntoConstraints = false 

    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1, constant: 0))    
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1, constant: 0)) 

    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0)) 
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131)) 
} 
+0

Jak uzyskać bieżące ograniczenia tego widoku? znasz to?? Nie mogę znaleźć dobrych rozwiązań. –

+0

Co masz na myśli przez "ten widok"? Zazwyczaj zapisujesz odniesienie do ograniczenia w usłudze podczas jej tworzenia lub używasz serwisu IBoutlet, jeśli korzystasz z storyboardu. – Paulw11

+0

Załóżmy, że nie chcę żadnego odniesienia IBOletlet ograniczenia tego widoku i istnieje właściwość tablicy UIView.rozwiązania, które zwracają tablicę. Jak uzyskać wiodący, końcowy, górny itp. Bez tworzenia właściwości odniesienia? –

2

zgadliście dzięki @ Paulw11 ... jest to rozwiązanie

view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1, constant: 0))  
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1, constant: 0))   
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0)) 
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131)) 

Również udało mi się przepisać go jak wynika z użyciem AutoLayoutDSL-Swift dla wszystkich zainteresowanych

view => gamePreview.trailing == view.trailing 
    => gamePreview.leading == view.leading 
    => gamePreview.height == 131 
    => gamePreview.top == view.top + self.navigationController!.navigationBar.bounds.height + UIApplication.sharedApplication().statusBarFrame.size.height 

Ostatnia linia jest trochę długo, ponieważ view.top odnosi się do naprawdę widok z góry i nie uważa wyściółkę dodany przez obu wysokościach StatusBar i navigationBar. Można je zastąpić stałymi, czekając, aż ktoś wymyśli bardziej eleganckie rozwiązanie.