5

Jeśli dodam do moich widoków dowolny rodzaj UIDynamicBehavior, całkowicie zepsuje to, gdy urządzenie zostanie obrócone. Oto co jest w układzie pionowym (wyświetlanie poprawnie):UIDynamik i obrót urządzenia

Correct Layout

I oto jest w krajobrazie, wszystko przerwał: Broken layout

nie wierzę, że jest to kwestia autolayout bo jeśli usunąć połączenia aby dodać UIDynamicBehavior działa dobrze bez problemów z autolayout. Nie są również zgłaszane żadne błędy autouzupełniania. Oto kod:

@interface SWViewController() { 
    UICollisionBehavior *coll; 
    UIDynamicAnimator *dynamicAnimator; 
} 

@implementation SWViewController 
- (void)viewDidLoad { 
    [super viewDidLoad]; 
    dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; 
} 

- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    [self setupCollisions]; // commenting this out fixes the layout 
} 

- (void)setupCollisions { 
    NSArray *dynamicViews = @[greenView]; 
    coll = [[UICollisionBehavior alloc] initWithItems:dynamicViews];  
    CGFloat topBound = CGRectGetMinY(greenView.frame); 
    [coll addBoundaryWithIdentifier:@"top" 
         fromPoint:CGPointMake(0, h1) 
          toPoint:CGPointMake(CGRectGetWidth(greenView.frame), h1)];  
    [dynamicAnimator addBehavior:coll]; 
} 

Gdybym przesłonić didRotateFromInterfaceOrientation widzę, że górna granica greenView nie wynika co autolayout mówi, że powinien (ponownie, usuwając wezwanie do setupCollisions poprawek tego).

Granice autoLayout na greenView są:

height = 200 
trailing space to Superview = 0 
leading space to Superview = 0 
bottom space to Superview = 0 
+0

Cześć, widzę, że używasz Collision Zachowanie tutaj. Co to oznacza bez zachowania grawitacji? Dzięki. – Unheilig

+0

W tym przykładzie nie używam nawet zachowania grawitacyjnego. Jeśli go wyłączysz, robi to samo. – swilliams

+1

Gorąco polecam oglądanie filmów WWDC na ten temat. Sesje 206 i 221 z tego roku. https://developer.apple.com/wwdc/videos/ Stwórz własne pytania na temat SO, jeśli je masz. – swilliams

Odpowiedz

2

Jedno rozwiązanie znalazłem przesłonić willRotateToInterfaceOrientation: i wyjąć UIDynamicItems a następnie ponownie dodać je do didRotateFromInterfaceOrientation:. To wydaje mi się dość hackowate i może potencjalnie wprowadzać błędy po dodaniu bardziej złożonych zachowań.

+0

Naprawdę nie kupuję tego jako odpowiedzi na ten problem, ponieważ ponownie przypisując zachowanie animatorowi, animacja powtarza się i do tego przy każdym obrocie ... nie jest elegancka. –

+0

Chciałbym zobaczyć lepszy (proszę)! Ponieważ tak, musiałem śledzić stan rzeczy i ostrożnie stosować zachowania, aby animacje nie były stuttery i powtarzały się. – swilliams

+0

Czy znalazłeś lepsze rozwiązanie? Zwłaszcza z iOS8 .. – Jan

0

Dynamiczny animator zmienia ramki zaangażowanych widoków. W rezultacie każda animacja zostałaby zakłócona przez wywołanie -[UIView setNeedsLayout] (widoki byłyby umieszczane w pozycjach ograniczonych bez względu na dynamiczny stan animacji.)

Moją obserwacją jest to, że używasz automatycznie generowanych więzów układu, a animator dynamiczny usuwa je z dowolny widok zaangażowany w animacji

Jeśli dodać własne ograniczenia układu. - oni utrzymują. - ale mogą zakłócać animację gdy widok jest proszony o ponowne obliczenie układ

0

Proszę dokładnie sprawdzić swoje ograniczenia auto układu

.

Miałem bardzo sim problem:

W moim przypadku mam wyeksportowany widok MyView, który ma zestaw ograniczeń: V: | - (0) - [MyView], V: [MyView] - (0) - |, H : [MyView: (== 300)] i działa dobrze bez użycia technologii UIDynami. Ale po dodaniu UIDynamiki do MyView, szerokość zmieniła się podczas obrotu, co jest bardzo podobne do twojego problemu.

Naprawiłem go dodając jeszcze jedno ograniczenie: H: | - (0) - [MyView]