IOS 自定義布局當中的坑

OlaCarbone 8年前發布 | 17K 次閱讀 iOS開發 移動開發 IOS AutoLayout

蠻久沒有寫文章了,最近在公司也是在趕項目,本周已經接近尾聲了,終于可以把在開發項目遇到的坑和積累的經驗寫一下啦,也算是年后的第一篇文章啦。

小編在項目正式開發的過成當中用到一些視圖為了方便使用還是會比較多的使用xib + autolayout來自定義一些控件或者布局。

簡單的自動布局小編就不說了,google一下。大把文章教你自定義布局,小編講一下自定義布局當中的坑。

首先簡單的一個項目入手,例如小編想要一個View里的控件實現如下圖的布局。這種應該是開發當中比較多用到的一種基本布局

實現某SuperView里有一個子View。子View要距離父View頂部100,左右各20,底部100,子View的高度自適應。

okay,看到約束這么明顯,是不是開始竊喜了。。上手就做。上下左右約束添加完畢后,添加高的約束。完成約束后。然后代碼設置子View的高度,然而發現并沒有什么卵用。

#import "ViewController.h"
#import "UIView+GFExtension.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.redView.height = 10.0;//然并卵的一句話
}

@end

對自動布局稍微了解一些的會添加子View的height的約束。然后關聯到ViewController.如圖

這時候代碼如下,

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *redViewHeight;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.redViewHeight.constant = 10.0;
}

@end

這時候運行項目,看到非但沒有解決問題,反倒在控制臺多出了一些警告信息。

imultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x7fc6d9c167e0 V:[UIView:0x7fc6d9c17190(10)]>",
    "<NSLayoutConstraint:0x7fc6d9c20950 V:[_UILayoutGuide:0x7fc6d9c1f4b0]-(100)-[UIView:0x7fc6d9c17190]>",
    "<NSLayoutConstraint:0x7fc6d9c209f0 V:[_UILayoutGuide:0x7fc6d9c1f4b0]-(286)-[UITextView:0x7fc6db808c00'Lorem ipsum dolor sit er ...']>",
    "<NSLayoutConstraint:0x7fc6d9c20a90 V:[UIView:0x7fc6d9c17190]-(108)-[UITextView:0x7fc6db808c00'Lorem ipsum dolor sit er ...']>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fc6d9c167e0 V:[UIView:0x7fc6d9c17190(10)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

其實透過警告信息,我們可以看到約束沖突,什么問題呢。問題就是你設置了上下左右的約束之后,然后又增大了子View的高度,這不是扯淡嘛。那到底怎么改變redView的高度呢。

在ios自動布局當中其實可以設置autolayout的優先級的。可能大家較多人都沒注意到這個選項,如圖

一共分為三個優先級,1000,750,250。那 C ontent Hugging Priority & content Compression Resistance Priority 又是什么呢。簡單解釋一下

contentHugging: 抱住使其在“內容大小”的基礎上不能繼續變大 

contentCompression: 撐住使其在在其“內容大小”的基礎上不能繼續變小
這兩個屬性分別可以設置水平方向和垂直方向上的,而且一個默認優先級是250, 一個默認優先級是750. 因為這兩個很有可能與其他Constraint沖突,所以優先級較低。
解決方法

既然知道了優先級這個問題,那我們開始看一下哪幾個約束沖突了,我們需要動態設置高度,所以豎直方向上約束沖突,然后我們查看一下豎直方向上的約束信息。

距離頂部100 優先級1000

距離底部100 優先級1000

高度78 優先級1000

因為我們需要動態設置高度。所以高度的優先級應該相對其他兩個應該高一些。設置1000.距離底部優先級設置成750.運行代碼。效果如下圖

左邊為storyBoard。右邊為模擬器。所以高度為10設置完成。當更改了底部的優先級之后,可以觀察到距離底部的實線變成虛線。

應用:

講了上面的小demo,下面就是應用了。簡單說一下應用場景,當我們在一個textView想顯示文本的時候,文本內容不確定,這時候就需要動態設置textView的高度了。

方法跟剛剛一樣。代碼如下

//
//  ViewController.m
//  autoLayout01
//
//  Created by goofygao on 5/7/16.
//  Copyright ? 2016 goofyy. All rights reserved.
//

#import "ViewController.h"
#import "UIView+GFExtension.h"
#import <UIKit/UIKit.h>

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *redView;
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *redViewHeight;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeight;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.redViewHeight.constant = 10.0;
    self.textView.text = @"床前明月光,疑是地上霜,舉頭望明月,低頭思故鄉";
    CGSize sizeToTextViewFitSize = [self.textView sizeThatFits:CGSizeMake(self.textView.width, self.textView.height)];
    self.textViewHeight.constant = sizeToTextViewFitSize.height;
}

@end

出來效果如圖。根據模擬器Color Blended Layer看效果圖如下

代碼地址:https://github.com/mgoofyy/BlogSource

來自: http://www.goofyy.com/blog/ios-autolayout高級01/

 本文由用戶 OlaCarbone 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!