如何使用带循环的 cgrect 垂直(而不是水平)添加 uiview objective c
How to add uiviews vertically (not horizontally) using cgrect with a loop objective c
我一直在尝试垂直而不是水平添加 uiview(换句话说,在一列中而不是在一行中),但我认为我没有正确理解代码。我可以改变和改变事情,我明白发生了什么,但我似乎无法垂直放置这些 uiviews。我已经尝试了数百种不同的东西,我正在阅读 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);
}
你知道bounds和frame的区别吗?在定位视图时,它们并没有什么不同——它们是天壤之别。
相应地,设置每个视图的中心以将它们精确定位在其父视图中,没有限制或奇怪:
https://developer.apple.com/documentation/uikit/uiview/1622627-center
否则,调用其父 UIView 的 setNeedsDisplay 方法。
如果不是那样,请在 UIView animateWithDuration:animations: 块参数中执行与子视图相关的代码。
情侣笔记...
首先,主要问题是您递增 x
而不是 y
,因此您得到的是“水平列表”而不是“垂直列表”。
其次 - 这与您的其他(已删除)问题更相关 - 如果您有不同的高度标签...
每次通过你的循环,你想要增加 y
标签(或视图)的高度加上 常量 垂直间距值。
因此,如果您有 4 个不同长度的标签,并且 word-wrapping 最终高度为:
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
。如果一个聊天线程收到数百条 back-and-forth 条消息,您真的不想添加数百个子视图和标签。
我一直在尝试垂直而不是水平添加 uiview(换句话说,在一列中而不是在一行中),但我认为我没有正确理解代码。我可以改变和改变事情,我明白发生了什么,但我似乎无法垂直放置这些 uiviews。我已经尝试了数百种不同的东西,我正在阅读 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);
}
你知道bounds和frame的区别吗?在定位视图时,它们并没有什么不同——它们是天壤之别。
相应地,设置每个视图的中心以将它们精确定位在其父视图中,没有限制或奇怪:
https://developer.apple.com/documentation/uikit/uiview/1622627-center
否则,调用其父 UIView 的 setNeedsDisplay 方法。
如果不是那样,请在 UIView animateWithDuration:animations: 块参数中执行与子视图相关的代码。
情侣笔记...
首先,主要问题是您递增 x
而不是 y
,因此您得到的是“水平列表”而不是“垂直列表”。
其次 - 这与您的其他(已删除)问题更相关 - 如果您有不同的高度标签...
每次通过你的循环,你想要增加 y
标签(或视图)的高度加上 常量 垂直间距值。
因此,如果您有 4 个不同长度的标签,并且 word-wrapping 最终高度为:
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
。如果一个聊天线程收到数百条 back-and-forth 条消息,您真的不想添加数百个子视图和标签。