在 Superview 中更改子视图的框架
Posted
技术标签:
【中文标题】在 Superview 中更改子视图的框架【英文标题】:Change Frame of Subview in Superview 【发布时间】:2018-10-01 20:29:54 【问题描述】:我有一个 ViewController,它在 viewDidLoad
中添加 UIView
、SpeciesImageView
作为子视图,并在 viewWillLayoutSubviews
中设置约束。
SpeciesImageView
没有 nib 文件。当我们在 viewDidLoad 中创建speciesImageView
时,它会调用SpeciesImageView
类中的initWithFrame
。
在手机旋转之前,它可以正常工作(横向和纵向)。我尝试将约束设置为speciesImageView.frame.size.width
,但这不起作用,因为当方向改变时不会调用initWithFrame
,因此speciesImageView
的高度/宽度保持不变。
另一方面,使用screenRect
不会改变UIView
的实际大小,它会改变它在超级视图中的大小。所以换句话说,我还没有找到一种方法来改变实际speciesImageView
在方向改变时的大小。
由于我不知道的原因,当您将其旋转回原始位置时,它会完全混乱。
- (void)viewDidLoad
self.tabBarController.tabBar.hidden=YES;
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.hidden = NO;
//self.navigationController.navigationBar.translucent = YES;
UIImage *plantinfo;
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_ios_6_1)
plantinfo = [UIImage imageNamed:@"plantinfo_frame.png"];
else
plantinfo = [UIImage imageNamed:@"plantinfo.png"];
UIBarButtonItem *tempButton = [[UIBarButtonItem alloc] initWithImage:plantinfo
style:UIBarButtonItemStylePlain
target:self
action:@selector(toggleText:)];
self.navigationItem.rightBarButtonItem = tempButton;
[tempButton release];
self.title = theSpecies.scientificName;
//[self.navigationItem.backBarButtonItem setTitle:@""];
self.navigationItem.backBarButtonItem.title = @"";
infoViewSegmentedControl.backgroundColor = [UIColor blackColor];
webView.backgroundColor = [UIColor blackColor];
_activityIndicator.hidden = YES;
[webView setOpaque:YES];
webView.delegate = self;
// Do double justification
[webView loadhtmlString:[self formatHTML:theSpecies] baseURL:nil];
showingInfoView = NO;
//
// Resize containerView, infoview according to iphone 5 screen size.
//
infoView.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
CGPoint screenOrigin = [[UIScreen mainScreen] bounds].origin;
CGSize viewSize = [[UIScreen mainScreen] bounds].size;
CGPoint origin = infoView.frame.origin;
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
infoView.frame = CGRectMake(screenOrigin.x,
screenOrigin.y + statusBarFrame.size.height,
viewSize.width,
viewSize.height - origin.y - statusBarFrame.size.height);
speciesImageView = [[SpeciesImageView alloc]
initWithFrame:CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height)];
else
infoView.frame = CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height - origin.y - statusBarFrame.size.height);
speciesImageView = [[SpeciesImageView alloc]
initWithFrame:CGRectMake(screenOrigin.x,
screenOrigin.y,
viewSize.width,
viewSize.height - statusBarFrame.size.height)];
speciesImageView.delegate = self;
[containerView addSubview:speciesImageView];
managedObjectContext = [(LeafletAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
[self parseImageURLArray];
-(void)viewWillLayoutSubviews
if(speciesImageView.window != nil)
CGRect screenRect = [[UIScreen mainScreen] bounds];
speciesImageView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *widthConst = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:screenRect.size.width];
NSLayoutConstraint *heightConst = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:screenRect.size.height];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:speciesImageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0.0];
[self.view addConstraints:@[widthConst, heightConst, bottomConstraint, rightConstraint]];
- (id)initWithFrame:(CGRect)frame
if (self = [super initWithFrame:frame])
imageScrollView = [[UIScrollView alloc] initWithFrame:frame];
imageScrollView.delegate = self;
imageScrollView.backgroundColor = [UIColor blackColor];
[self addSubview:imageScrollView];
imageScrollView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *widthConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.width];
NSLayoutConstraint *heightConst = [NSLayoutConstraint constraintWithItem:imageScrollView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:imageScrollView.frame.size.height];
NSLayoutConstraint *rightConstraint = [NSLayoutConstraint
constraintWithItem:imageScrollView
attribute:NSLayoutAttributeRight
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0.0];
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint
constraintWithItem:imageScrollView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0.0];
[self addConstraints:@[widthConst, heightConst, bottomConstraint, rightConstraint]];
return self;
【问题讨论】:
如果你希望图像视图的宽度被屏幕宽度改变你应该设置左右superView的约束而不是它的宽度约束 【参考方案1】:如果您希望您的视图调整为超级视图的大小, 那么你需要这样的东西(将边距设置为你喜欢的任何东西):
CGFloat margin = 0;
NSString * visualFormatH = [NSString stringWithFormat:@"|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
options:0
metrics:Nil
views:@@"speciesImageView": speciesImageView]];
NSString * visualFormatV = [NSString stringWithFormat:@"V:|-(%f)-[speciesImageView]-(%f)-|", margin, margin];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
options:0
metrics:Nil
views:@@"speciesImageView": speciesImageView]];
现在,speciesImageView 将在 superview 框架发生变化时调整其框架。
这是一个通用示例:
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView * sampleView = [UIView new];
sampleView.backgroundColor = [UIColor redColor];
sampleView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:sampleView];
CGFloat margin = 0;
NSString * visualFormatH = [NSString stringWithFormat:@"|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatH
options:0
metrics:Nil
views:@@"sampleView": sampleView]];
NSString * visualFormatV = [NSString stringWithFormat:@"V:|-(%f)-[sampleView]-(%f)-|", margin, margin];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:visualFormatV
options:0
metrics:Nil
views:@@"sampleView": sampleView]];
Auto Layout Getting Started
Auto Layout Visual Format Documentation
【讨论】:
我是否在 SpeciesImageViewClass 的 viewWillLayoutSubviews 中执行此操作? 您可以在viewDidLoad
中将speciesImageView 添加到它的superView 后立即执行此操作
我将speciesImageView
添加到容器视图中,这不是它的父视图
我不知道上述原因是不是这个解决方案对我不起作用的原因
containerView 是否有适当的约束?它的框架变化正确吗?以上是关于在 Superview 中更改子视图的框架的主要内容,如果未能解决你的问题,请参考以下文章
从其 superView 中删除 UIView 并将其框架扩展到全屏