提问人:John 提问时间:1/14/2022 最后编辑:WillekeJohn 更新时间:3/13/2022 访问量:80
如何使用带有循环目标 c 的 cgrect 垂直(而不是水平)添加 uiviews
How to add uiviews vertically (not horizontally) using cgrect with a loop objective c
问:
我一直在尝试垂直而不是水平添加uiviews(换句话说,在一列而不是一行中),但我认为我没有正确理解代码。我可以改变和改变事情,我明白发生了什么,但我似乎无法垂直放置这些 uiview。我已经尝试了数百种不同的东西,我正在阅读 cgrect,但我仍然找不到该怎么做。如果有人能为我指出正确的方向,我将不胜感激。
- (void) generateChat
{
int xcounter = 0;
int longest = 0;
_chatListRect.backgroundColor= [UIColor whiteColor];
NSArray *commaChat01 = @[@"test 01",@"test 02",@"test 03",@"test 04"];
for (NSString* str in commaChat01){
CGSize result = [[UIScreen mainScreen]bounds].size;
CGFloat
x= 0.0, xt = 0.0,
y= 0.0, yt = 0.0,
w= 0.0, wt = 0.0,
h= 0.0, ht = 0.0;
if (result.width >= 0 && result.width <= 1500){
x = 15; xt = 7.5;
y = 10; yt = 7.5;
w = 75; wt = 65;
h = 75; ht = 75;
}
UIView *testview =[[UIView alloc]initWithFrame:CGRectMake((xcounter*(x+w))+x, y, w,h)];
UIView *labelrect = [[UIView alloc]initWithFrame:CGRectMake(yt, xt, wt, ht)];
testview.backgroundColor = UIColor.redColor;
labelrect.backgroundColor = UIColor.blueColor;
[testview.layer setCornerRadius:2.0f];
[testview.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[testview.layer setBorderWidth:0.0f];
UILabel *testlabel = [[UILabel alloc]initWithFrame:labelrect.bounds];
testlabel.adjustsFontSizeToFitWidth = true;
[testlabel setFont:[UIFont fontWithName:@"HelveticaNeue-Medium" size:20]];
testlabel.textAlignment = NSTextAlignmentCenter;
[self.view layoutIfNeeded];
NSString *line1 = str;
testlabel.text = line1;
[labelrect addSubview:testlabel];
[testview addSubview:labelrect];
[_chatListRect addSubview:testview];
xcounter = xcounter+1;
}
longest =xcounter;
xcounter =0;
if (longest < xcounter){longest = xcounter;}
_chatListRect.contentSize = CGSizeMake(100*longest,500);
}
答:
你知道边界和框架的区别吗?在定位视图时,它们并没有细微的不同——它们是天壤之别。
因此,设置每个视图的中心,以将它们精确地放置在其上视图中,而不受限制或奇怪:
https://developer.apple.com/documentation/uikit/uiview/1622627-center
否则,请调用其 UIView 父级的 setNeedsDisplay 方法。
如果没有,请在 UIView animateWithDuration:animations: 块参数中执行与子视图相关的代码。
几张纸条...
首先,主要问题是你正在递增而不是 ,所以你得到的是一个“水平列表”而不是“垂直列表”。x
y
其次 - 这与您的另一个(已删除)问题更明显相关 - 如果您有不同的高度标签......
每次循环时,您都希望按标签(或视图)的高度加上恒定的垂直间距值递增。y
因此,如果您有 4 个不同长度的标签,并且换行的高度为:
80, 40, 30, 30
从,并且需要垂直间距,则帧的值为:y = 20
20-points
y
y = 20;
y += 80 + 20;
y += 40 + 20;
y += 30 + 20;
y += 30 + 20;
所以,这是你的代码的修改版本......我将其简化为仅使用标签,但如果将标签嵌入到“包含”视图中,则相同的过程将适用:
_chatListRect.backgroundColor = [UIColor whiteColor];
NSArray *commaChat01 = @[
@"test 01 - long enough that this label will almost certainly need to wrap onto multiple lines.",
@"test 02 - short",
@"test 03 - longer string",
@"test 04 - longer, and will probably need to wrap",
@"test 05 - short",
@"test 06 - longer, and will probably need to wrap",
@"test 07 - short",
@"test 08 - long enough that this label will almost certainly need to wrap onto multiple lines.",
@"test 09 - short",
@"test 10 - longer string",
@"test 11 - longer, and will probably need to wrap",
@"test 12 - short",
@"test 13 - short",
@"test 14 - short",
@"test 15 - longer, and will probably need to wrap",
@"test 16 - short",
];
CGSize result = [[UIScreen mainScreen]bounds].size;
// we want the first label 20-points from the top
CGFloat y = 20.0;
// we want 20-points vertical spacing between labels
CGFloat vSpacing = 20.0;
// we want the labels to start 15-points from the left
CGFloat x = 15.0;
// we want the same "padding" (15-points) on the right as the left
// so max width for the labels is
CGFloat maxWidth = result.width - 30.0;
// to get the width of the widest label
CGFloat widest = 0;
for (NSString* str in commaChat01) {
// create the label
UILabel *testlabel = [UILabel new];
// set label font properties
[testlabel setFont:[UIFont fontWithName:@"HelveticaNeue-Medium" size:20]];
testlabel.textAlignment = NSTextAlignmentCenter;
testlabel.backgroundColor = UIColor.cyanColor;
// we want the text to wrap if needed
testlabel.numberOfLines = 0;
// set label text
testlabel.text = str;
// calculate label size restricted to maxWidth
CGSize labelSize = [testlabel sizeThatFits:CGSizeMake(maxWidth, CGFLOAT_MAX)];
// set the label frame
testlabel.frame = CGRectMake(x, y, labelSize.width, labelSize.height);
// add label to _chatListRect
[_chatListRect addSubview:testlabel];
// increment y by label Height plus Spacing
y += testlabel.frame.size.height + vSpacing;
widest = MAX(widest, testlabel.frame.size.width);
}
// content size
// Width = widest label plus left-indent
// Height = y (which has been incremented each time through the loop)
_chatListRect.contentSize = CGSizeMake(widest + 15.0, y) ;
希望如果您浏览该代码并检查注释,这对您来说是有意义的。
然而。。。如果你正在构建一个“聊天应用程序”,你几乎肯定希望使用一个或一个。如果一个聊天线程有几百条来回消息,你真的不想添加几百个子视图和标签。UITableView
UICollectionView
评论
CGRectMake((xcounter*(x+w))+x, y, w,h)
,则您只修改原点 x。这就是为什么你最终拥有水平并排视图的原因。只需在纸上用轴画出它,您就会更好地理解或平均坐标......UIStackView