以编程方式从XIB调整自定义UIView的大小
我有以下问题:我在XIB
文件中创build了一个自定义的UIView
类和它的布局。 假设我在XIB中的自定义视图的大小是150 x 50。我已经启用了sizeClasses
(wAny hAny)和AutoLayout
。 在模拟度量标准中,我设置了Size = Freeform
, Status Bar = None
, other = Inferred
。
我的自定义UIView
类的代码如下所示:
#import "CustomView.h" @implementation CustomView #pragma mark - Object lifecycle - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self setup]; } return self; } #pragma mark - Private & helper methods - (void)setup { if (self.subviews.count == 0) { [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil]; self.bounds = self.view.bounds; [self addSubview:self.view]; } } @end
在我想要添加这个自定义UIView
UIViewController
中,我已经制作了虚拟UIView(我在界面生成器中设置了这个大小),我想添加我的CustomView
, 我希望我的CustomView
适合容器视图的边界 。
我正在尝试这样做:
_vCustomView = [[CustomView alloc] init]; _vCustomView.translatesAutoresizingMaskIntoConstraints = NO; [_vContainer addSubview:_vCustomView]; [_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]]; [_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]]; [_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]]; [_vContainer addConstraint:[NSLayoutConstraint constraintWithItem:_vCustomView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_vContainer attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]];
但没有运气。 假设我的容器视图是300 x 100,当我将自定义的UIView
添加到它时, 我的自定义视图仍然是150 x 50 。
我试图没有容器视图工作 – 将我的自定义UIView
对象直接添加到我的UIViewController
并设置它的宽度和高度:
-
autoLayout
约束 - 通过初始化我的自定义
UIView
时使用initWithFrame
但是再次 – 没有运气。 自定义视图始终为150 x 50。
有人可以向我解释如何以编程方式添加我在XIB
制作的自定义UIView
并使用autoLayout
约束来调整它 ?
提前谢谢了。
编辑#1:错误时,我试图在我的CustomView上运行Andrea的代码
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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSLayoutConstraint:0x17489b760 V:[UIView:0x17418d820(91)]>", "<NSLayoutConstraint:0x170c9bf80 V:|-(0)-[CustomView:0x1741da7c0] (Names: '|':CustomView:0x1741da8b0 )>", "<NSLayoutConstraint:0x170c9bfd0 V:[CustomView:0x1741da7c0]-(0)-| (Names: '|':CustomView:0x1741da8b0 )>", "<NSLayoutConstraint:0x170c9be90 V:|-(0)-[CustomView:0x1741da8b0] (Names: '|':UIView:0x17418d820 )>", "<NSLayoutConstraint:0x170c9bee0 CustomView:0x1741da8b0.bottom == UIView:0x17418d820.bottom>", "<NSAutoresizingMaskLayoutConstraint:0x170c9dba0 h=--& v=--& CustomView:0x1741da7c0.midY == + 25.0>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x170c9bfd0 V:[CustomView:0x1741da7c0]-(0)-| (Names: '|':CustomView:0x1741da8b0 )>
编辑#2:它的工作!
@Andrea补充说:
view.translatesAutoresizingMaskIntoConstraints = NO;
在他的:
- (void) stretchToSuperView:(UIView*) view;
方法,一切工作如我所料。
感谢@Andrea。
我猜主要的问题是,当你将xib添加到内容视图中时,你不使用自动布局。
在init方法中添加子视图之后,请调用该方法,传递xib的视图:
- (void) stretchToSuperView:(UIView*) view { view.translatesAutoresizingMaskIntoConstraints = NO; NSDictionary *bindings = NSDictionaryOfVariableBindings(view); NSString *formatTemplate = @"%@:|[view]|"; for (NSString * axis in @[@"H",@"V"]) { NSString * format = [NSString stringWithFormat:formatTemplate,axis]; NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat:format options:0 metrics:nil views:bindings]; [view.superview addConstraints:constraints]; } }
[编辑]
你的设置代码应该是这样的:
- (void)setup { if (self.subviews.count == 0) { [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self options:nil]; self.bounds = self.view.bounds; [self addSubview:self.view]; [self stretchToSuperView:self.view]; } }
注意,我已经添加了内部拉伸视图view.translatesAutoresizingMaskIntoConstraints = NO;
[编辑2]
我会尽量详细说明我的答案。 使用自动布局,当你添加一个没有设置约束的视图时,autolayout自动将自动调整遮罩转换为约束,它们的默认属性是UIViewAutoresizingNone
,这意味着不会自动resize。
您的XIB视图被添加到其父没有约束,没有autoresize的可能性,从而保持其原来的大小。 既然你希望你的观点根据你的观点resize,你有两个select:
- 将xib视图的自动调整掩码更改为灵活的宽度和高度,但是它们需要匹配父对象的大小,否则将不会有完整的掩码
- 添加一些限制这两个视图的约束来相应地改变父变化。 而你在XIB视图和它的父视图之间实现了这样的说法:尾随/领先和顶部/底部之间的距离是0.就像你在他们的边界上粘贴一些胶水。 为此,您需要将autotranslateresize的掩码设置为约束为NO,或者您可以在日志中发布一些冲突。
你以后要做的是将视图(托pipeXIB视图)的约束添加到它的超级视图,但是在XIB和它的父级之间没有约束,因此autolayout不知道如何调整XIB视图的大小。
视图层次结构中的每个视图都应该有自己的约束。
希望这有助于更好地理解。
在你的代码中你应该有这样的东西:
首先,你要改变宽度约束的IBOutlet
,无论是在viewController或在你的CustomView
(我不知道你有什么逻辑来计算约束值)。
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *widthConstraint;
然后,在你想更新常量值的方法中,你会得到如下的结果:
-(void)updateWidth { [self.widthConstraint setConstant:newConstant]; [self.view layoutIfNeeded]; // self.view must be an ancestor of the view //If you need the changes animated, call layoutIfNeeded in an animation block }
希望这对你有用。 祝你好运!