相關方法
@property(nonatomic) BOOL autoresizesSubviews; // default is YES. if set, subviews are adjusted according to their autoresizingMask if self.bounds changes
@property(nonatomic) UIViewAutoresizing autoresizingMask; // simple resize. default is UIViewAutoresizingNone
注:parentview設定autoresizesSubviews,subview設定autoresizingMask,parentview.autoresizesSubviews = YES,subview.autoresizingMask才有意義
UIViewAutoresizing
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
x-axis上UIViewAutoresizing可組合值:
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
y-axis上UIViewAutoresizing可組合值:
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
原理
subview在父坐标系x-axis上divide 3個portions:left,width,right
- left:subview左邊緣距離父坐标系原點在x-axis上距離,即subview.frame.origin.x,可能為負
- width:subview自身width,即subview.bounds.size.width,恒為正
- right:parentview.bounds.size.width - left - width,可能為負
當parentview.bounds改變(parentview.autoresizesSubviews = YES),根據subview.autoresizingMask值把parentview的bounds.size.width變化量按比例配置設定到這3個portions上 parentview.bounds.size.width變化量Δwidth = new parentview.bounds.size.width - parentview.bounds.size.width(可能為負) 如果subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin,則:
- new left = left + Δwidth * left / (left + width + right)
- new width = width + Δwidth * width / (left + width + right)
- new right = new parentview.bounds.size.width - new left - new width
如果subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin,則:
- new left = left + Δwidth * left / (left + right)
- new width = width
- new right = new parentview.bounds.size.width - new left - new width
如果subview.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin,則:
- new left = left + Δwidth * left / left
- new width = width
- new right = new parentview.bounds.size.width - new left - new width
如果subview.autoresizingMask = UIViewAutoresizingNone,則:
- new left = left
- new width = width
- new right = new parentview.bounds.size.width - new left - new width
注:left,width,right,Δwidth都是帶符号運算,當然width恒為正,left,right和Δwidth可能為負,left + width + right恒等于parentview.bounds.size.width subview在父坐标系y-axis上divide 3個portions:top,height,bottom,原理同x-axis,不再贅述
autoresizing局限性
autoresizing是ios為了适應裝置螢幕尺寸發生改變時,盡可能的不改變代碼而能完美适配所引入的一種簡易layout機制,autoresizing核心是同比例縮放,是以适用于裝置螢幕尺寸長寬比相同,随着apple後續引入了不同長寬比裝置,autoresizing突顯了其局限性:
- autoresizing在表示parent view和sub view之間的pos和size關系時能表示的組合非常有限,在x-axis或y-axis一維空間内隻能表示有限的8種(1 + 3 + 3 + 1)組合關系,在x-axis和y-axis二維空間内隻能表示有限的64種(8 * 8)組合關系,而且隻能按某種比例機制,是以不能表示parent view和sub view之間更多更精确的pos和size關系