UICollectionView Headers 重叠
UICollectionView Headers Overlapping
我有一个具有以下相关方法的 collectionView:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];
ScoreboardReusableView *view = nil;
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"scoreboardHeader"
forIndexPath:indexPath];
//view.backgroundColor = [UIColor yellowColor];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
//label.text = [NSString stringWithFormat:@"%@ vs %@", thisScoreboard.awayteam, thisScoreboard.hometeam];
label.text = [NSString stringWithFormat:@"%ld", (long)indexPath.section];
[view addSubview:label];
return view;
}
return nil;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(self.view.frame.size.width, 34);
}
但是,标签文本重叠。这是 collectionView 的两个屏幕截图。第 0 节和第 1 节(注意文本如何不重叠):
以及第 2 和第 3 节(此处和所有后续部分 header 的文本重叠):
我的 header xib ScoreboardReusableView
是完全空白的,因为无论我在其中放入什么(例如,UILabel 或 UIImageView,它都不会显示在 UICollectionView 中 Header ).我最好在 xib 中设计 header,但由于那不起作用,我尝试以编程方式进行,但现在标签重叠了。
ScoreboardReusableView 是空白的,但它是可重用的。您必须将 UILabel 放入 header xib 并在之后为其设置文本。
例如:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];
ScoreboardReusableView *view = nil;
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"scoreboardHeader"
forIndexPath:indexPath];
view.label.text = [NSString stringWithFormat:@"%ld", (long)indexPath.section];
return view;
}
return nil;
}
Collection 视图 re-use 个单元格和 header 个单元格。当 header 滚动到屏幕外时,它会被添加到 queue,并且将 re-used 用于下一个要在屏幕上滚动的 header。这意味着您在 collectionView:viewForSupplementaryElementOfKind:
方法中的配置代码将在不同索引路径的相同 header 视图中再次 运行。由于每次配置代码 运行 时您只是添加一个标签,因此它们将一个堆叠在另一个之上。
正确的方法是在 headerView 上添加一个标签 属性,这样它的文本就可以更改了。但是...
no matter what I put in it (e.g., a UILabel or a UIImageView), it would not show up
这是你真正的问题。你在 xib 上启用了自动布局吗?如果是这样,请务必为标签添加约束,否则它将具有零宽度和高度,从而产生您描述的效果。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *reusableview=nil;
reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
NSArray *viewsToRemove = [reusableview subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
if (reusableview==nil) {
reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
}
reusableview.backgroundColor=[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];
UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width-90, 30)];
[lblTitle setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
lblTitle.textColor=HTAtHomeColor;
[reusableview addSubview:lblTitle];
UILabel *lblCount=[[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-80, 0, 70, 30)];
lblCount.textAlignment=NSTextAlignmentRight;
lblCount.textColor=[UIColor blackColor];
[lblCount setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
lblCount.text=[NSString stringWithFormat:@"%d Section Header",indexPath.row];
[reusableview addSubview:lblCount];
return reusableview;
}
return nil;
}
Swift3个版本,希望对你有帮助
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var reusableview: UICollectionReusableView?
reusableview = nil
reusableview = playersCollectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "collViewHeader", for: indexPath as IndexPath)
if kind == UICollectionElementKindSectionHeader {
//remove all previous subviews:
if let views = reusableview?.subviews {
for view in views {
view.removeFromSuperview()
}
}
//----------
if reusableview == nil {
reusableview = UICollectionReusableView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 50))
}
//init label
let label = UILabel.init(frame: CGRect(x: 10.0, y: 20.0, width: self.view.frame.width-20, height: 25.0)) //-20 from width to make it no go out of screen bounds
label.textColor = UIColor.blue //you may set your color here :)
label.adjustsFontSizeToFitWidth = true
label.text = "your text here"
reusableview?.addSubview(label)
}
return reusableview!
}
我有一个具有以下相关方法的 collectionView:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];
ScoreboardReusableView *view = nil;
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"scoreboardHeader"
forIndexPath:indexPath];
//view.backgroundColor = [UIColor yellowColor];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
//label.text = [NSString stringWithFormat:@"%@ vs %@", thisScoreboard.awayteam, thisScoreboard.hometeam];
label.text = [NSString stringWithFormat:@"%ld", (long)indexPath.section];
[view addSubview:label];
return view;
}
return nil;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
return CGSizeMake(self.view.frame.size.width, 34);
}
但是,标签文本重叠。这是 collectionView 的两个屏幕截图。第 0 节和第 1 节(注意文本如何不重叠):
以及第 2 和第 3 节(此处和所有后续部分 header 的文本重叠):
我的 header xib ScoreboardReusableView
是完全空白的,因为无论我在其中放入什么(例如,UILabel 或 UIImageView,它都不会显示在 UICollectionView 中 Header ).我最好在 xib 中设计 header,但由于那不起作用,我尝试以编程方式进行,但现在标签重叠了。
ScoreboardReusableView 是空白的,但它是可重用的。您必须将 UILabel 放入 header xib 并在之后为其设置文本。
例如:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if (kind == UICollectionElementKindSectionHeader) {
Scoreboard *thisScoreboard = [self.scoreboards objectAtIndex:indexPath.section];
ScoreboardReusableView *view = nil;
view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:@"scoreboardHeader"
forIndexPath:indexPath];
view.label.text = [NSString stringWithFormat:@"%ld", (long)indexPath.section];
return view;
}
return nil;
}
Collection 视图 re-use 个单元格和 header 个单元格。当 header 滚动到屏幕外时,它会被添加到 queue,并且将 re-used 用于下一个要在屏幕上滚动的 header。这意味着您在 collectionView:viewForSupplementaryElementOfKind:
方法中的配置代码将在不同索引路径的相同 header 视图中再次 运行。由于每次配置代码 运行 时您只是添加一个标签,因此它们将一个堆叠在另一个之上。
正确的方法是在 headerView 上添加一个标签 属性,这样它的文本就可以更改了。但是...
no matter what I put in it (e.g., a UILabel or a UIImageView), it would not show up
这是你真正的问题。你在 xib 上启用了自动布局吗?如果是这样,请务必为标签添加约束,否则它将具有零宽度和高度,从而产生您描述的效果。
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {
UICollectionReusableView *reusableview=nil;
reusableview = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
NSArray *viewsToRemove = [reusableview subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
if (reusableview==nil) {
reusableview=[[UICollectionReusableView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30)];
}
reusableview.backgroundColor=[UIColor colorWithRed:234.0/255.0 green:234.0/255.0 blue:234.0/255.0 alpha:1.0];
UILabel *lblTitle=[[UILabel alloc] initWithFrame:CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width-90, 30)];
[lblTitle setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
lblTitle.textColor=HTAtHomeColor;
[reusableview addSubview:lblTitle];
UILabel *lblCount=[[UILabel alloc] initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width-80, 0, 70, 30)];
lblCount.textAlignment=NSTextAlignmentRight;
lblCount.textColor=[UIColor blackColor];
[lblCount setFont:[UIFont fontWithName:@"Ubuntu-Light" size:12]];
lblCount.text=[NSString stringWithFormat:@"%d Section Header",indexPath.row];
[reusableview addSubview:lblCount];
return reusableview;
}
return nil;
}
Swift3个版本,希望对你有帮助
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
var reusableview: UICollectionReusableView?
reusableview = nil
reusableview = playersCollectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "collViewHeader", for: indexPath as IndexPath)
if kind == UICollectionElementKindSectionHeader {
//remove all previous subviews:
if let views = reusableview?.subviews {
for view in views {
view.removeFromSuperview()
}
}
//----------
if reusableview == nil {
reusableview = UICollectionReusableView.init(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 50))
}
//init label
let label = UILabel.init(frame: CGRect(x: 10.0, y: 20.0, width: self.view.frame.width-20, height: 25.0)) //-20 from width to make it no go out of screen bounds
label.textColor = UIColor.blue //you may set your color here :)
label.adjustsFontSizeToFitWidth = true
label.text = "your text here"
reusableview?.addSubview(label)
}
return reusableview!
}