iOS 자동 레이아웃 - 노트

9673 단어
iOS 자동 레이아웃
개인 Github 블로그, 관심
1 autoresizing
    autoresizingMask:                 “         ”。         ,        autoresizingMask          ,        。

단점:
  • 그 묘사 인터페이스의 변화 규칙이 유연하지 않아 많은 변화 규칙이 정확하게 묘사할 수 없다.autoresizingMask 배율은 UIKit 내부에서 계산되며 개발자는 배율의 정확한 값을 지정할 수 없습니다.
  • 변화 규칙은 부모 보기와 하위 보기 사이만 바탕으로 할 수 있고 동급 보기나 크로스 보기 간의 관계를 구축할 수 없다.

  • 예제:
        - (void)viewDidLoad {
            [super viewDidLoad];
        
            UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 200)];
            containerView.backgroundColor = [UIColor blueColor];
            [self.view addSubview:containerView];
        
            UILabel *text = [[UILabel alloc] initWithFrame:CGRectZero];
            text.text = @"1231312";
            [containerView addSubview:text];
            text.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth;
            text.frame = CGRectMake(0, 0, containerView.bounds.size.width - 20, 100);
        
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
              containerView.frame = CGRectMake(0, 0, 300, 200);
              NSLog(@"%@ %@ %@ %@", @(text.frame.origin.x), @(text.frame.origin.y), @(text.frame.size.width),
                    @(text.frame.size.height));
            });
        }
    

    2 autolayout
    autolayout:                              。                , :y = m*x + c,  x y                 ,m     ,c   。               (Layout Constraint)。
    

    2.1 NSLayoutConstraint
        NS_CLASS_AVAILABLE_IOS(6_0)
        @interface NSLayoutConstraint : NSObject
        ...
        @property (readonly, assign) id firstItem;
        @property (readonly) NSLayoutAttribute firstAttribute;
        @property (readonly) NSLayoutRelation relation;
        @property (readonly, assign) id secondItem;
        @property (readonly) NSLayoutAttribute secondAttribute;
        @property (readonly) CGFloat multiplier;
        @property CGFloat constant;
        ...
        +(instancetype)constraintWithItem:(id)firstItem attribute:(NSLayoutAttribute)firstAttribute 
         relatedBy:(NSLayoutRelation)relation 
         toItem:(id)secondItem attribute:(NSLayoutAttribute)secondAttribute 
         multiplier:(CGFloat)multiplier constant:(CGFloat)constant;
    

    공식:firstItem.firstAttribute {==,<=,>=} secondItem.secondAttribute * multiplier + constant
    설명:firstItem과secondItem은 각각 인터페이스에서 제약을 받는 보기와 참조된 보기입니다.그들이 반드시 형제 관계나 부자 관계가 아니라 그들이 공통된 조상시도를 가지고 있다면 된다는 점은 autoresizingMask가 할 수 없는 것이다.fir
    stAttribute와 secondAttribute는 각각 firstItem과 secondItem의 레이아웃 속성 (NSLayoutattribute) 이다.firstItem과secondItem은 반드시 같은 값이 아니며, 특정한 보기의 높이가 다른 보기의 너비와 같은 제약을 정의할 수 있습니다.NSLayout Attribute NotAn Attribute는 특정한 보기에 너비나 높이를 정확하게 지정해야 할 때 second Item은 nil이고 second Attribute는 NSLayout Attribute Nott An Attribute이다.relation은 레이아웃 관계(NSLayoutRelation)를 정의합니다.
        - (void)viewDidLoad {
            [super viewDidLoad];
            // Do any additional setup after loading the view, typically from a nib.
            
            UIView *v1 = [UIView new];
            v1.backgroundColor = [UIColor blueColor];
            v1.translatesAutoresizingMaskIntoConstraints = NO;
            [self.view addSubview:v1];
            
            
            NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:v1
                                                                             attribute:NSLayoutAttributeTop
                                                                             relatedBy:NSLayoutRelationEqual
                                                                                toItem:self.view
                                                                             attribute:NSLayoutAttributeTop
                                                                            multiplier:1
                                                                              constant:0];
            NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:v1
                                                                              attribute:NSLayoutAttributeLeft
                                                                              relatedBy:NSLayoutRelationEqual
                                                                                 toItem:self.view
                                                                              attribute:NSLayoutAttributeLeft
                                                                             multiplier:1
                                                                               constant:0];
            NSLayoutConstraint *rightConstraint = [NSLayoutConstraint constraintWithItem:v1
                                                                               attribute:NSLayoutAttributeRight
                                                                               relatedBy:NSLayoutRelationEqual
                                                                                  toItem:self.view
                                                                               attribute:NSLayoutAttributeRight
                                                                              multiplier:1
                                                                                constant:0];
            NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:v1
                                                                                attribute:NSLayoutAttributeHeight
                                                                                relatedBy:NSLayoutRelationEqual
                                                                                   toItem:self.view
                                                                                attribute:NSLayoutAttributeHeight
                                                                               multiplier:0.5
                                                                                 constant:0];
            // iOS8   
        //    [v1 addConstraint:topConstraint];
        //    [v1 addConstraint:leftConstraint];
        //    [v1 addConstraint:rightConstraint];
        //    [v1 addConstraint:heightConstraint];
            // iOS8   
            topConstraint.active = YES;
            leftConstraint.active = YES;
            rightConstraint.active = YES;
            heightConstraint.active = YES;
        }
    

    2.2 VFL
    2.3 자체 컨텐트 치수 구속, 수정 구속, 레이아웃 애니메이션
                :    ,            ,    4     (       x、    y、  w   h)。  ,             ,      UILabel、  UIButton、    UIImageView ,          (Intrinsic Content Size),                     。    ,                    ,                  。    “  ”  ,       。
    

    구속의 주요 속성은 다음과 같습니다.
        @property (readonly, assign) id firstItem;
        @property (readonly) NSLayoutAttribute firstAttribute;
        @property (readonly) NSLayoutRelation relation;
        @property (readonly, assign) id secondItem;
        @property (readonly) NSLayoutAttribute secondAttribute;
        @property (readonly) CGFloat multiplier;
            
        /* Unlike the other properties, the constant may be modified after constraint creation.  Setting the constant on an existing constraint performs much better than removing the constraint and adding a new one that's just like the old but for having a new constant.
         */
        @property CGFloat constant;
    

    구속을 업데이트하려면 다음과 같이 하십시오.
    코드를 사용하여 제약을 수정할 때, 제약의 상수 값인constant만 수정할 수 있습니다.일단 제약을 만들면 다른 읽기 전용 속성은 수정할 수 없습니다. 특히 비례계수 멀티플렉스도 읽기 전용입니다.
    삭제 구속을 추가하려면 다음과 같이 하십시오.
        - (void)keyboardWillShow:(NSNotification *)notification
        {
            self.labelCenterYNormalCons.active = NO;
            self.labelCenterYKeyboardCons.active = YES;
        }
        
        - (void)keyboardWillHide:(NSNotification *)notification
        {
            self.labelCenterYKeyboardCons.active = NO;
            self.labelCenterYNormalCons.active = YES;
        }
    

    가능한 한 active를 NO로 설정해야 하는 제약을 설정한 다음에 active를 YES로 설정해야 하는 제약을 설정합니다. 위의 두 문장을 뒤바꾸면 실행 시 제약 오류가 발생할 수 있습니다.
    구속조건 우선 순위를 수정하려면 다음과 같이 하십시오.
        - (void)keyboardWillShow:(NSNotification *)notification
        {
            self.labelCenterYNormalCons.priority = UILayoutPriorityDefaultLow;
            self.labelCenterYKeyboardCons.priority = UILayoutPriorityDefaultHigh;
        }
        
        - (void)keyboardWillHide:(NSNotification *)notification
        {
            self.labelCenterYKeyboardCons.priority = UILayoutPriorityDefaultLow;
            self.labelCenterYNormalCons.priority = UILayoutPriorityDefaultHigh;
        }
    

    주의해야 할 것은 선택적 구속의 우선 순위만 수정할 수 있다는 것입니다. 즉,
  • 우선 순위를 1000보다 작은 값에서 1000으로 변경할 수 없음
  • 우선 순위를 1000에서 1000보다 작은 값으로 변경할 수 없음
  • 예를 들어 250에서 1000으로 우선순위를 변경하면 이상이 발생합니다.
    자신 내용 사이즈 제약의 압출 저항과 당김 저항 효과
    용수철은 자신의 고유한 길이가 있고, 외력 작용이 있을 때 용수철은 외력 작용에 저항하여 고유의 길이에 최대한 가깝게 한다.
       :        ,          ,              ,               。 
       :        ,          ,              ,               。
    

    자신의 내용 사이즈 제약에 대해 Hug 값은 늘어짐 저항 우선순위를, CompressionResistance 값은 압축 저항 우선순위를 나타낸다.Hug 값이 높을수록 늘어나기 어렵고,Compression Resistance 값이 높을수록 압축되기 어렵다.이 두 가지 모두 자신의 내용에 대한 사이즈다.이 두 값이 높을수록 자동 레이아웃을 할 때view의 실제 레이아웃은 자신의 내용 사이즈에 가깝다.그들이 표현한 것은 자신의 내용 사이즈 제약이 대외적으로 제약을 가하는 저항력이다.
    참조 문서:
  • iOS 8 Auto Layout 인터페이스 자동 레이아웃 시리즈 1 - 자동 레이아웃의 기본 원리
  • iOS 8 Auto Layout 인터페이스 자동 레이아웃 시리즈 2 - Xcode Interface Builder를 사용한 레이아웃 구속조건 추가
  • iOS 8 Auto Layout 인터페이스 자동 레이아웃 시리즈 3- 코드로 레이아웃 구속조건 추가
  • iOS 8 Auto Layout 인터페이스 자동 레이아웃 시리즈 4-VFL을 사용하여 레이아웃 구속조건 추가
  • iOS 8 Auto Layout 인터페이스 자동 레이아웃 시리즈 5 - 자체 내용 사이즈 제약, 수정 제약, 레이아웃 애니메이션
  • 좋은 웹페이지 즐겨찾기