天天看點

uikit——UIView——autoresizing

相關方法

@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關系