我问这个(某种程度上)简单的问题只是为了挑剔,因为有时候我担心我可能会对许多UIView的API进行误操作,特别是在涉及自动布局时.
为了使它变得非常简单,我将使用一个例子,假设我需要一个具有图像图标和多行标签的UIView子类; 我想要的行为是我的视图高度随着标签的高度而变化(以适应文本内部),而且,我正在使用Interface builder进行布局,所以我有这样的事情:

使用一些约束来为图像视图提供固定的宽度和高度,并将固定的宽度和位置(相对于图像视图)固定到标签:

现在,如果我在标签上设置了一些文本,我希望视图在高度上调整大小以适应它,或者保持与xib中相同的高度.在自动布局之前我会做到这样的事情:
在CustoView子类文件中,我会sizeThatFits:像这样重写:
- (CGSize) sizeThatFits:(CGSize)size{
//this stands for whichever method I would have used
//to calculate the height needed to display the text based on the font
CGSize labelSize = [self.titleLabel intrinsicContentSize];
//check if we're bigger than what's in ib, otherwise resize
CGFloat newHeight = (labelSize.height <= 21) ? 51: labelSize.height+20;
size.height = newHeight;
return size;
}
Run Code Online (Sandbox Code Playgroud)
而且我会称之为:
myView.titleLabel.text = @"a big text to display that should be more than a line";
[myView …Run Code Online (Sandbox Code Playgroud) 以下问题是这个问题的延续:
主要思想是每个视图都应该声明它是"首选"(内在)大小,以便AutoLayout可以知道如何正确显示它.UILabel只是一个视图无法知道显示所需大小的情况的示例.这取决于提供的宽度.
正如mwhuss指出的那样,setPreferredMaxLayoutWidth实现了使标签跨越多行的技巧.但这不是主要问题.问题是我在何时何地获得此宽度值作为参数发送到setPreferredMaxLayoutWidth.
我设法制作看似合法的东西,所以如果我错了,请纠正我,如果你知道更好的方法,请告诉我.
在UIView的
-(CGSize) intrinsicContentSize
Run Code Online (Sandbox Code Playgroud)
我setPreferredMaxLayoutWidth根据self.frame.width我UILabels.
UIViewController的
-(void) viewDidLayoutSubviews
Run Code Online (Sandbox Code Playgroud)
是我知道的第一个回调方法,主视图的子视图是用它们在屏幕上居住的确切帧来指定的.然后,从该方法I内部操作我的子视图,使其内在大小无效,以便UILabel根据指定给他们的宽度分成多行.
我正在使用iOS 6自动布局进行开发
我想记录一条显示视图框宽的消息.
我可以在屏幕上看到textView.
但我得到的宽度和高度为零,我错过了什么?
NSLog(@"textView = %p", self.textView);
NSLog(@"height = %f", self.textView.frame.size.height);
NSLog(@"width = %f", self.textView.frame.size.width);
textView = 0x882de00
height = 0.000000
width = 0.000000
Run Code Online (Sandbox Code Playgroud) 我有一个UITableViewCell,它有两个UITextFields(没有边框).以下约束用于设置水平布局.
@"|-10-[leftTextField(>=80)]-(>=10)-[rightTextField(>=40)]-10-|"
没有什么花哨的,并且按预期工作.

如您所见,上部textField具有正确的大小.较低的textField以空文本开头,由于空文本,它是80点宽.当我在编辑textField中键入文本时,文本向左滚动,它不会改变其宽度.
我不喜欢这样,当用户键入textField时,textField的宽度应该调整.
在我看来,应该开箱即用.通过实施IBAction该UIControlEventEditingChanged事件,我可以确认实际输入改变intrinsicContentSize的也是UITextField的.
但是,在textField不再是第一个响应者之前,宽度不会改变.如果我将光标放入另一个textField,则设置已编辑的textField的宽度.对于我想要的东西,这有点晚了.
这些注释掉的行是我尝试过的,没有任何成功:
- (IBAction)textFieldDidChange:(UITextField *)textField {
[UIView animateWithDuration:0.1 animations:^{
// [self.contentView removeConstraints:horizontalConstraints];
// [self.contentView addConstraints:horizontalConstraints];
// [self.contentView layoutIfNeeded];
// [self.contentView setNeedsLayout];
// [self.contentView setNeedsUpdateConstraints];
}];
NSLog(@"%@", NSStringFromCGSize(textField.intrinsicContentSize));
}
Run Code Online (Sandbox Code Playgroud)
有人知道我错过了什么吗?我有什么办法让这项工作成功?
在我的storyboard应用程序中,我尝试添加额外UITextField的界面.但我得到标题所说的例外.我使用SwiftAutoLayout库.这是我的代码:
// MARK: - IBOutlets
@IBOutlet weak var passwordTextField: UITextField!
// MARK: - Properties
let userIdTextField = UITextField()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.passwordTextField.keyboardType = .NumberPad
if getCurrentUserId() == nil {
self.view.addSubview(userIdTextField)
userIdTextField.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addConstraints([userIdTextField.al_leading == passwordTextField.al_leading,
userIdTextField.al_trailing == passwordTextField.al_trailing,
userIdTextField.al_top == passwordTextField.al_bottom + 8])
userIdTextField.placeholder = "Enter User Id..."
}
}
Run Code Online (Sandbox Code Playgroud) 目前,我正在使用一个UITableView包含在其中的其他视图UIScrollView.我希望UITableView它的高度与其内容高度相同.
更复杂的是,我还插入/删除行以提供手风琴效果,这样当用户点击一行时,它将显示该行的更多细节.
我已完成插入/删除,但目前它没有更新UIScrollView,这是它的超级视图,以便UIScrollView重新计算内容大小,并且正确显示UITableView其中的其他视图UIScrollView.
我怎样才能实现这一点,以便UIScrollView在我更改内容时调整大小并正确布置其内容UITableView?我目前正在使用自动布局.
我们有选择地使用自动布局约束,主要是为了定位与可编辑字段元素相关的标签(通常是UITextView,UITextField).但是,自从为这些字段实现自动布局以来,每当我们卸载视图,解除分配等时,我们都会看到一个令人讨厌的异常并崩溃.异常发生的原因是它试图在卸载视图之前从视图中删除约束.
我们的视图/控制器层次结构如下:
UITableViewController (plain style, but with cell appearance to mimic grouped style)
--> UITableViewCell
----> UIViewController (container for editable form)
------> UICollectionViewController (editable form)
--------> UICollectionViewCell
-----------> UIViewController (editable field)
--------------> UILabel (field label) **HAS CONSTRAINTS**
--------------> UITextView / UITextField (field value) **HAS CONSTRAINTS**
Run Code Online (Sandbox Code Playgroud)
很多时候,当上层表格单元被解除分配/替换/重新加载时,我们会看到一个巨大的异常,然后崩溃,因为它试图释放/卸载其中的视图层次结构.
我试图通过捕获异常(没有帮助)并通过在释放/卸载(in viewWillDisappear:)之前强制删除受影响的视图和所有子视图上的所有约束来缓解崩溃,它似乎没有帮助.我甚至试图逐个删除这些约束,看看是否有一个特别是导致麻烦但是当我们打电话removeConstraint:或removeConstraints:在容器上准备消失时它们都会爆炸.
我很困惑!这是我们例外的一小部分 - 大约有3000行被切断了,所以如果你需要更多,请问.
Exception while deallocating view: { Rows:
0x18911270.posErrorMarker == 4 + 1*0x18911270.negError + 1*0x189112f0.marker + -1*0x189113f0.negError + 1*0x189113f0.posErrorMarker + 1*0x18911a60.marker + -0.5*0x1892dae0.negError + 0.5*0x1892dae0.posErrorMarker + …Run Code Online (Sandbox Code Playgroud) 我猜他们必须参考struts和spring模型,但我找不到它们.当你NSLog约束他们有时表现为无证类的描述字符串NSAutoresizingMaskLayoutConstraint.我已经注意到了至少3种不同类型:h=---,h=--&,h=-&-具有水平和垂直版本.
调试受约束的布局时,它们会出现很多变化.
警告: leading or trailing horizontal alignment before iOS 11
在故事板文件中的一个场景上编译Xcode 9.1时,我收到了警告.还有其他故事板(部署目标为iOS 10.0),但警告会显示在特定Storyboard文件的特定场景中.
如果我在显示警告的场景上将部署目标更改为iOS 11.0但是我不想这样做,则警告会被抑制.
有人遇到这个案子吗?
我有一个简单的UICollectionView,单元格有一个UITextView.UITextView受限于单元格的边缘,因此它们应保持与单元格大小相同的大小.
我遇到的问题是,由于某种原因,当我通过collectionView指定单元格大小时,这些约束不起作用:layout:sizeForItemAtIndexPath:.
我在故事板中将单元格大小设置为320x50.如果我使用sizeForItemAtIndexPath:返回大小为单元格大小2倍的大小,则尽管我设置了约束,但UITextView仍保持相同的高度.我正在使用Xcode 6 GM.
我的视图控制器代码是:
@implementation TestViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.collectionView.delegate = self;
self.collectionView.dataSource = self;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UICollectionViewCell *c = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
NSLog(@"%f", c.frame.size.height);
UITextView *tv = (UITextView *)[c viewWithTag:9];
NSLog(@"%f", tv.frame.size.height);
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)collectionView.collectionViewLayout; …Run Code Online (Sandbox Code Playgroud) autolayout ×10
ios ×8
cgsize ×1
cocoa ×1
cocoa-touch ×1
iphone ×1
nslog ×1
objective-c ×1
storyboard ×1
swift ×1
uilabel ×1
uiscrollview ×1
uitableview ×1
uitextfield ×1
uiview ×1
xcode ×1