2016-07-21 11 views
6

W kilku miejscach w mojej aplikacji otrzymuję zerowe rozmiary ramek, w których otrzymałem ramkę. Wpłynęło to na mnie szczególnie podczas tworzenia okrągłych obiektów poprzez róg o wartości size/2.Xcode 8 ustawia inaczej rozmiar ramki. Jak znaleźć więcej informacji?

Na przykład w Xcode 7 to działało w porządku:

class AvatarUIButton: UIButton { 
    required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    layer.masksToBounds = true 
    layer.cornerRadius = bounds.size.width/2 
    } 
} 

Ale teraz w Xcode 8 muszę to zrobić:

class AvatarUIButton: UIButton { 
    override var bounds: CGRect { didSet { 
    layer.cornerRadius = bounds.size.width/2 
    }} 

    required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self.layer.masksToBounds = true 
    } 
} 

W tym przykładzie, zmiana jest zapewne lepiej/bardziej oczywisty. Mam inną sytuację, która jest znacznie mniej izolowana, obejmującą ramkę 0 w TableHeaderView, która jest tylko dla kodu xcode 8.

Szukam informacji o wydaniu, dyskusji na liście dyskusyjnej lub podobnej, która omawia zmianę kolejności określania rozmiaru klatki więc mogę dowiedzieć się, co się zmieniło i jak mogę to naprawić.

+0

mam ten sam problem. To jest problem z AutoLayout. W moim przypadku ramki rejestrują się jako (0, 0, 1000, 1000). Ustawienie promienia narożnika na stałą wartość (niezliczone) powoduje ponowne pojawienie się widoku. Bez użycia AutoLayout problem nie istnieje. – Tuslareb

+0

Miałem podobny problem, z podziałem w niestandardowej komórce tabeli. Wywiad miał ograniczenia dotyczące pozycji i rozmiaru. _Przedtem komórka została wyświetlona ramka dla tego wydziału to {(0,0), (1000,1000)}. Niestandardowy rysunek oparty na tej ramce najwyraźniej nie działał. Podczas debugowania i przeglądania widoków znalazłem, że ramka jest poprawna dopiero po wyświetleniu widoku na ekranie. Moim rozwiązaniem było dodanie '[cell layoutIfNeeded]' zaraz po odjęciu komórki z 'cellForRowAtIndexPath:'. Rozwiązał problem dla mnie i mogłem dalej obliczyć promień narożnika w innym miejscu. –

+0

Nauka: tak, klatki mają teraz rozmiar 1000 lub zero w widoku 'viewWillAppear' (w zależności od tego, jaki masz xcode beta). Ale w 'viewWillAppear' możesz wywołać' view.layoutIfNeeded() ', aby poprawnie dopasować ramki. – SimplGy

Odpowiedz

2

W Xcode 8, Apple powiedzieć:

Xcode 8 usuwa możliwość konfiguracji poglądów bez ograniczeń z ramą za zmianę klasy wielkości. Widoki bez ograniczeń mogą wyglądać inaczej po kompilacji przy pomocy Xcode 8 podczas przełączania klas wielkości w środowisku wykonawczym . Idąc dalej, użyj ograniczników i maski automatycznej regulacji, aby uzyskać pożądany układ. (25894544)

We wcześniejszych wersjach Xcode, definiowaliśmy projekt na ViewDidLoad. Ale tutaj różne elementy nie zostały utworzone (i też ograniczenia), więc widok został utworzony z rozmiarem w Storyboard.

Teraz, w Xcode 8, nie możemy już tego robić. Musimy mieć ograniczenia, ponieważ ramka nie jest inicjowana (dlatego niektórzy z was mają następujące wartości rozmiaru ramki: 0, 0, 1000, 1000). Na przykład uczyń go w ViewDidAppear i będzie działać poprawnie. Ale zobaczysz na początku swój przycisk bez promienia narożnika kilka razy.

Więc, co można zrobić, to skorzystać z tej funkcji (tutaj w Objective C) (gdzie chcesz, nawet w funkcji obciążenia):

[self performSelector:@selector(setCornerToMyButton) withObject:NULL afterDelay:0]; 

Można pu opóźnienie chcesz, ale nawet z 0 działa.

I zmienić promień w tej funkcji takich jak to na przykład:

- (void) setCornerToMyButton { 
    //Do what you want... 
    layer.masksToBounds = true 
    layer.cornerRadius = bounds.size.width/2 
} 

Nadzieja to pomoże.

+1

Nie rozmiar w 'viewDidLoad', nie sądzę, że gwarantuje rozmiary ramki. Używam 'viewWillAppear', wszelkie informacje na ten temat? Myślałem, że klatki będą miały rozmiar (nie "viewDidLoad"), ale nie są w kodzie xcode. 8. Wykonywanie rozmiaru 'viewDidAppear' powoduje przesunięcie układu, jak to zauważyłeś, więc jest to niedopuszczalne. Używanie opóźnienia wydaje się niepoprawne/hacky, chociaż ufam ci, że to działa. Myślę, że platforma powinna mieć "gotowe do zorganizowania" wydarzenie. Myślałem, że to "viewWillAppear". – SimplGy

+0

Jeśli chcesz wymusić aktualizację w następnej klatce, po prostu użyj 'dispatch_async (dispatch_get_main_queue(), {})' zamiast 'performSelector: withObject: afterDelay:'. Myślę, że 'performSelector' jest dość głupi, zwłaszcza w szybkim tempie. – MrJre

2

w Twoim przypadku wystarczy zadzwonić:

override func draw(_ rect: CGRect) { 
    self.layoutIfNeeded() 
    layer.masksToBounds = true 
    layer.cornerRadius = bounds.size.width/2 
} 

na UIViewController zadzwoń view.layoutIfNeed() zaraz po Super.viewDidLoad(), działa jak urok; Nie wiem, co jest przyczyną tego problemu (jeśli jest problem) tak czy inaczej wydaje się, że ładowanie widoku nie "układa" widoku ani już nie używa autoregulacji ani autolayoutu w tej sprawie, więc tak jak powiedziałem na razie, że może użyć tego rozwiązania, aby lepiej zrozumieć, co zmieniło się dokładnie w przypadku klas niestandardowych (niestandardowy przycisk na przykład), można zastąpić layoutSubviews() lub layoutIfNeeded(), tam znajdziesz ramkę/układ, którego szukasz i zastosujesz niezależnie od zmian chcesz

0

dostałem odpowiedź właśnie

[super viewDidLoad]; 
[self.myNeedFrameView layoutIfNeeded]; 
+2

Czy możesz wyjaśnić, gdzie ten kod zostanie dodany w stosunku do pierwotnego pytania. Jeśli to możliwe, nawet "dlaczego" rozwiązuje problem? – Jmons

+0

Witamy w Stack Overflow! Ten fragment kodu może rozwiązać problem, ale nie wyjaśnia, dlaczego i w jaki sposób odpowiada na pytanie. Proszę [załączyć wyjaśnienie swojego kodu] (// meta.stackexchange.com/questions/114762/explaining-entirely-code-ans -answers), ponieważ to naprawdę pomaga poprawić jakość twojego posta. Pamiętaj, że odpowiadasz na pytanie przeznaczone dla czytelników w przyszłości, a te osoby mogą nie znać powodów sugestii dotyczących kodu. ** Flagi/recenzenci: ** [Odpowiedzi tylko w formie kodu, takie jak ten, przejdź na dół, nie usuwaj!] (// meta.stackoverflow.com/a/260413/2747593) –

+0

Rozumiem odpowiedź, ale nie dotyczy tego dokładnego pytania. Ponieważ pokazuje to UIView, nie ma haka 'viewDidLoad'. @DanielBarbarian ma rację, że ten problem dotyczy również kontrolerów View i to jest w tym przypadku poprawka. – SimplGy

Powiązane problemy