天天看点

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关系