【问题标题】:Change Frame of Subview in Superview在 Superview 中更改子视图的框架
【发布时间】:2018-10-01 20:29:54
【问题描述】:

我有一个 ViewController,它在 viewDidLoad 中添加 UIViewSpeciesImageView 作为子视图,并在 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的约束而不是它的宽度约束

标签: ios objective-c view-hierarchy initwithframe


【解决方案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 是否有适当的约束?它的框架变化正确吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
相关资源
最近更新 更多