Автоматично оформление и ограничения за iPad

Доста съм объркан относно новата функция за автоматично оформление на xCode 4.5.

Ето какво искам да направя,

Чрез настройването на разкадровката имам настройка за този портретен изглед. въведете описание на изображението тук

Чрез използване на автоматично оформление и ограничения (и щифтове), как мога да трансформирам оформлението, когато е обърнато към пейзаж по този начин? въведете описание на изображението тук

Опитах да кодирам и променя CGRect (размер и местоположение на координатите) на изгледите, когато са пейзажни, но без резултат.


person ruelluna    schedule 24.05.2013    source източник


Отговори (2)


NSLayoutConstraints заместват необходимостта от CGRects в Auto Layout. Първо, опишете вашето оформление с думи. Ето как бих описал вашия пример за портрет:

  • Ширината на червено е 60% от неговия суперизглед.
  • Височината на Blue е 55% от неговата superview.
  • Левият и десният ръб на Blue се допират до суперизгледите му.
  • Левият ръб на червеното докосва суперизгледа, десният ръб на червеното е близо до левия ръб на жълтото, а десният ръб на жълтото докосва суперизгледа.
  • Горният ръб на синьото докосва неговия суперизглед, долният ръб на синьото е близо до горния ръб на червеното, а долният ръб на червеното докосва неговия суперизглед.
  • Долният ръб на синьото е близо до горния ръб на жълтото, а долният ръб на жълтото докосва неговия суперизглед.

Ето метод, който премахва съществуващите ограничения на superview, след което прилага нови ограничения за дадената ориентация на интерфейса.

- (void) buildConstriantsForInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Remove existing constraints.
    [superview removeConstraints:superview.constraints] ;
    // Build an array to hold new constraints.
    NSMutableArray* constraints = [NSMutableArray new] ;

    // Add 2 constraints that apply to both Portrait & Landscape orientations.
    [constraints addObject:[NSLayoutConstraint constraintWithItem:red  attribute:NSLayoutAttributeWidth  relatedBy:NSLayoutRelationEqual  toItem:superview  attribute:NSLayoutAttributeWidth  multiplier:0.6  constant:0]] ;
    [constraints addObject:[NSLayoutConstraint constraintWithItem:blue  attribute:NSLayoutAttributeHeight  relatedBy:NSLayoutRelationEqual  toItem:superview  attribute:NSLayoutAttributeHeight  multiplier:0.55  constant:0]] ;

    // Build a dictionary to store references to NSViews.
    NSDictionary* views = NSDictionaryOfVariableBindings(superview, blue, red, yellow) ;
    // To eliminate repeated NSLayoutConstraint code, build an array of Format Strings with which to build constraints.
    NSArray* formatStrings ;
    if ( UIInterfaceOrientationIsPortrait(interfaceOrientation) ) {
        formatStrings = @[@"H:|[blue]|", @"H:|[red]-[yellow]|", @"V:|[blue]-[red]|", @"V:[blue]-[yellow]|"] ;
    }
    else {
        formatStrings = @[@"H:|[blue]-[yellow]|", @"H:|[red]-[yellow]", @"V:|[blue]-[red]|", @"V:|[yellow]|"] ;
    }

    for ( NSString* formatString in formatStrings ) {
        [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:formatString  options:0  metrics:nil  views:views]] ;
    }

    // Add the newly created constraints.
    [superview addConstraints:constraints] ;
}

Можете да извиквате този метод всеки път, когато изгледът се зарежда или завърта.

-(void) viewDidLoad {
    superview.translatesAutoresizingMaskIntoConstraints = NO ;
    [self buildConstriantsForInterfaceOrientation:self.interfaceOrientation] ;
}

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self buildConstriantsForInterfaceOrientation:toInterfaceOrientation] ;
}
person John Sauer    schedule 24.05.2013

Автоматичното оформление е страхотно за изразяване на връзката на един обект с друг и за разрешаване на конфликти - но няма вградени условни концепции. За вашето оформление мисля, че може да намерите най-лесно да добавяте и премахвате ограничения върху въртенето, вижте https://developer.apple.com/library/ios/#documentation/AppKit/Reference/NSLayoutConstraint_Class/NSLayoutConstraint/NSLayoutConstraint.html за подробности как да ги добавите.

Можете също така да зададете вашите ограничения и да коригирате приоритетите, така че да работи правилното нещо при ротация, но ще са необходими някои тестове и корекции, за да стане правилно. Направих някои тестове на място и мисля, че го правя правилното нещо, но това е само с празни изгледи, които нямат присъщ размер на съдържанието. Въпреки това, ето какво мисля, че е необходимо, за да направите всичко чрез сценарий:

  • Уверете се, че синият изглед има ширина ‹= портретната ширина и >= минималната пейзажна ширина
  • Уверете се, че червеният изглед има минимална височина
  • Фиксирайте ширината на жълтия изглед и задайте височината да бъде >= височината на портрета
  • Закрепете всеки изглед към ъгъла, в който винаги ще остане (напр. щифт след края и отдолу към суперизглед за жълто)
  • Подравнете горната част на жълтия изглед със синия изглед с нисък приоритет
  • Увеличете устойчивостта на компресия на съдържанието за жълто

Мисля за това като започване със синия изглед с максимален размер с доста висок приоритет, а жълтият изглед знае как да се разширява нагоре, но е с нисък приоритет. Когато се завърти, синият изглед запазва максималния си размер, което освобождава жълтия изглед да се разширява нагоре. След това попълвам необходимите ограничения, за да поддържам нещата в съответствие.

Това е доста сложно за описване в текст, ето екранна снимка, показваща трите изгледа и ограниченията между тях. Не показва всичко, но можете поне да проверите връзките между изгледите: xcode показва ограничения

person James    schedule 24.05.2013