动态调整大小的视图定位

Posted

技术标签:

【中文标题】动态调整大小的视图定位【英文标题】:Views positioning with dynamic resizing 【发布时间】:2014-05-20 07:09:36 【问题描述】:

我正在尝试创建一个高度动态增加的UITextView。 有一个UIView 可以将此UITextViewUIButton 分组。

我已经为UITextViewTextDidChangeNotification 通知添加了一个观察者到NSnotificationCenter

根据当前点击文字的高度,我新建一个CGRect

CGRect newRect = [contentTextView.text boundingRectWithSize:CGSizeMake(222, CGFLOAT_MAX)
                                                         options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@NSFontAttributeName:font context:nil];

然后,我改变当前UIView的大小:

CGRect tmp = commentView.frame;
CGRect fitRectForView = CGRectMake(tmp.origin.x, tmp.origin.y - abs(newRectH - commentView.frame.size.height), tmp.size.width, newRect.size.height);
            commentView.frame = fitRectForView; 

最后,我改变了UITextView的高度:

CGRect fitRectForTextView = CGRectMake(contentTextView.frame.origin.x, contentTextView.frame.origin.y, contentTextView.frame.size.width,newRectH);
            contentTextView.frame = fitRectForTextView;

这是我的contentTextView变量在拟合前后的原点和大小的日志:

//Before
contentTextView origin : 0.000000 ; 0.000000
contentTextView size : 33.000000 ; 251.000000
//After
contentTextView origin : 0.000000 ; 0.000000
contentTextView size : 84.000000 ; 251.000000

通过这个截图,你可以看到只有我的commentView 的高度在变化。 我在send 按钮上设置了一个约束,以使其保持在UIView(commentView)的底部,但它没有效果。

我找不到我的错误。

这是我的第一个来源:create-a-multi-line-uitextfield

【问题讨论】:

【参考方案1】:

如果你的 UITextView 在你的视图控制器的视图中而不是在键盘输入附件视图中,那么这就是我通常使用约束的方式:

-(void)viewDidLoad

    ...

    myTextView = [[UITextView alloc] init];
    myTextView.scrollEnabled = NO;

    myTextView.translateAutoresizingMaskIntoConstraints = NO;

    // -----------------------------------------------
    // set textview delegate for delegate method
    // -----------------------------------------------
    myTextView.delegate = self;

    // -----------------------------------------------
    // put your code to setup all the constraint 
    // for your textView here
    //
    // Note: alternatively, you can set your constraints
    // using Interface Builder.
    // -----------------------------------------------




// -----------------------------------------------
// This is the UITextView delegate method so make
// sure your .h file has conformed to 
// UITextViewDelegate method
// -----------------------------------------------
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text

    ...

    // let autolayout know the textView needs to relayout
    [textView invalidateIntrinsicContentSize];

    return YES;

其他信息

如果您希望按钮显示在视图的底部,则需要将按钮设置为固定到 UIView 容器的底部。

在代码中有约束,它是这样完成的:

id views = @"containerView": self.containerView, @"contentTextView": self. contentTextView, @"myButton": self.myButton;

// make your container view expand to fill up your root view
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView]|" options:0 metrics:nil views:views]];

// text view constraints
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-10-[contentTextView]-10-[myButton]-10-|" options:0 metrics:nil views:views]];
[self.containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[contentTextView]-10-|" options:0 metrics:nil views:views]];

// button constraints

// note here, we make the button bottom edge always same as text view's bottom edge.

[self.containerView addConstraint:[NSLayoutConstraint constraintWithItem:self.myButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.contentTextView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]];

【讨论】:

我宁愿从 Interface Builder 添加约束。这样我就可以知道我在做什么。顺便一提。我不明白为什么当commentView 的高度在增长时按钮不在底部。你有想法吗 ?我认为解决方案可能来自这一点。 你可以在任何你喜欢的地方添加你的约束,重要的部分是 invalidateIntrinsicContentSize 行和你初始化你的 UITextView 的方式。至于按钮没有出现在底部,请确保您设置了一个约束,使按钮的底部始终位于 UIView 的底部(请参阅更新的答案)。 我注意到我的contentTextView 的高度永远不会更新(根据日志)。怎么可能? UITextView 需要将 scrollEnabled 属性设置为 NO 如果您使用我相信的约束。 我试过了,但也没用。我从这个问题中找到了灵感create-a-multi-line-uitextfield

以上是关于动态调整大小的视图定位的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局调整同级视图的大小时,使用子视图重新定位 UIView 不起作用

Interface Builder 以小增量降低情节提要、调整大小和重新定位视图

动态调整视图大小 osx

如何在堆栈视图中动态调整文本视图的大小

使绝对定位的孩子随他们的上级动态调整大小

使用 Interface Builder 动态调整 UILabel 的大小并在其下方重新定位 UIView