iOS7에서 UITableViewCell 구분 기호가 사라짐
UITableViewiOS 7에서만 이상한 문제가 있습니다.
UITableViewCellSeparator첫 번째 행 위와 마지막 행 아래에서 사라집니다. 때때로 행이나 일부 스크롤 동작을 선택한 후 나타납니다.
내 경우 tableView에는 Storyboardwith UITableViewStylePlain스타일 에서로드됩니다 . 문제는 확실하지 않으며 UITableViewCellSeparatorStyle기본값에서 변경되지 않습니다 UITableViewCellSeparatorStyleSingleLine.
Apple Dev Forums ( here 및 here ) 에서 읽을 때 다른 사람들에게 그러한 문제가 있으며 몇 가지 해결 방법이 있습니다.
Workaround: disable the default selection and recreate the behaviour in a method
trigged by a tapGestureRecognizer.
그러나 나는 여전히 그런 분리기의 이상한 행동의 이유를 찾고 있습니다.
어떤 아이디어?
업데이트 : XCode 5.1 DP 및 iOS 7.1 베타에서 보았 듯이 Apple 은이 문제를 해결하려고했습니다. 이제 구분 기호는 때때로 새로 고친 후 마지막 행 아래에 필요에 따라 표시되지만 테이블 뷰 생성 후에는 표시되지 않습니다.
영향을받는 셀의 하위 뷰 계층 구조를 덤프하고 _UITableViewCellSeparatorView가 숨김으로 설정되어 있음을 발견했습니다 . 그것이 보이지 않는 것은 당연합니다!
나는 오버라이드 layoutSubviews내에서 UITableViewCell서브 지금은 분리가 확실하게 표시됩니다
목표 -C :
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
subview.hidden = NO;
}
}
}
스위프트 :
override func layoutSubviews() {
super.layoutSubviews()
guard let superview = contentView.superview else {
return
}
for subview in superview.subviews {
if String(subview.dynamicType).hasSuffix("SeparatorView") {
subview.hidden = false
}
}
}
여기에 제안 된 다른 솔루션은 나에게 일관되게 작동하지 않거나 어리석은 것처럼 보입니다 (사용자 정의 1px 바닥 글보기 추가).
이것은 나를 위해 일했다 :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// fix for separators bug in iOS 7
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
또한 분리 누락 된 문제를했고 나는 때만 문제가 발생한 것을 발견 heightForRowAtIndexPath한 소수의 개수를 돌려줍니다 . 해결책:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return ceil(yourHeight) // Ceiling this value fixes disappearing separators
}
밝은 회색 배경색으로 테이블의 머리글과 바닥 글에 높이 1의 UIView를 추가하려고 했습니까? 기본적으로 첫 번째와 마지막 구분 기호를 조롱합니다.
sam
이 대리자 메서드를 사용하여 문제를 해결했습니다. 이제 깜박 거리지 않습니다.
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// fix for separators bug in iOS 7
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
}
-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
// fix for separators bug in iOS 7
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
}
앱에서이 문제가 발생했습니다. 사용자가 셀을 선택하면 새 테이블보기가 탐색 컨트롤러 스택으로 푸시 된 다음 사용자가이를 제거 할 때 구분 기호가 누락되었습니다. 테이블 뷰 대리자 메소드 [self.tableView deselectRowAtIndexPath:indexPath animated:NO];를 사용하여 해결했습니다 didSelectRowAtIndexPath.
필요한 경우 더 쉬운 해결 방법이 있습니다 (데이터가 다시로드되고 기본 애니메이션이 완료된 후 셀을 선택하고 선택 취소하십시오).
그냥 추가하십시오 :
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
가장 쉬운 해결책은 셀을 다시로드 한 후 위의 셀을 다시로드하는 것입니다.
if (indexPath.row > 0) {
NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
[self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationNone];
}
iOS 8과 iOS 9 (베타 1) 모두에서 작동하는 간단하고 깨끗한 솔루션
다음은 간단하고 깨끗 하며 방해가되지 않는 해결 방법입니다. 구분 기호를 수정하는 범주 메서드를 호출해야합니다.
셀의 계층 구조를 따라 가고 구분 기호를 숨기기 해제하기 만하면됩니다. 이처럼 :
for (UIView *subview in cell.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
subview.hidden = NO;
}
}
내가 권장하는 것은 이것을 다음과 같이 UITableViewCell의 카테고리에 추가하는 것입니다.
@interface UITableViewCell (fixSeparator)
- (void)fixSeparator;
@end
@implementation UITableViewCell (fixSeparator)
- (void)fixSeparator {
for (UIView *subview in self.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
subview.hidden = NO;
}
}
}
@end
현재 선택된 셀과 다른 셀에서 구분 기호가 사라질 수 있으므로 테이블 뷰의 모든 셀 에서이 수정 프로그램을 호출하는 것이 좋습니다 . 이를 위해 UITableView에 다음과 같은 범주를 추가 할 수 있습니다.
@implementation UITableView (fixSeparators)
- (void)fixSeparators {
for (UITableViewCell *cell in self.visibleCells) {
[cell fixSeparator];
}
}
@end
이를 사용하면 -fixSeparatostableView가 사라지는 작업 직후에 tableView를 호출 할 수 있습니다 . 내 경우, 호출 한 후였다 [tableView beginUpdates]와 [tableView endUpdates].
처음에 언급했듯이 iOS 8과 iOS 9에서 모두 테스트했습니다 .iOS 7에서도 작동한다고 가정하지만 거기서 시도 할 방법이 없습니다. 아시다시피, 이것은 셀의 내부를 피들 링하여 향후 릴리스에서 작동을 멈출 수 있습니다. 그리고 애플은 이론적으로 (0.001 % 확률) 앱으로 인해 앱을 거부 할 수는 있지만, 당신이하고있는 일을 어떻게 알 수 있는지 알 수 없습니다 (정적 분석기는 무언가로 클래스의 접미사를 확인할 수 없습니다) 나쁘다, IMO).
@ ortwin-gentz의 의견에 따라이 솔루션은 iOS 9에서 작동합니다.
func fixCellsSeparator() {
// Loop through every cell in the tableview
for cell: UITableViewCell in self.tableView.visibleCells {
// Loop through every subview in the cell which its class is kind of SeparatorView
for subview: UIView in (cell.contentView.superview?.subviews)!
where NSStringFromClass(subview.classForCoder).hasSuffix("SeparatorView") {
subview.hidden = false
}
}
}
(스위프트 코드)
내 tableView의 일부 메소드에서 endUpdates () 를 호출 한 후 fixCellsSeparator () 함수를 사용합니다 .
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Perform some stuff
// ...
self.tableView.endUpdates()
self.fixCellsSeparator()
}
이 솔루션이 누군가에게 도움이되기를 바랍니다.
에어 포그의 답을 보완하십시오.
따라서 기본적으로 두 개의 UITableDelegate 메소드를 구현해야합니다. 여기 iOS7과 iOS6에서 모두 작동하는 솔루션이 있습니다.
#define IS_OS_VERSION_7 (NSFoundationVersionNumber_iOS_6_1 < floor(NSFoundationVersionNumber))
#define UIColorFromRGB(hexRGBValue) [UIColor colorWithRed:((float)((hexRGBValue & 0xFF0000) >> 16))/255.0 green:((float)((hexRGBValue & 0xFF00) >> 8))/255.0 blue:((float)(hexRGBValue & 0xFF))/255.0 alpha:1.0]
// 전체 화면을 덮지 않으면 셀 아래에 빈 표 격자가 숨겨집니다.
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIView *view = nil;
if (IS_OS_VERSION_7 /* && <is this the last section of the data source> */)
{
CGFloat height = 1 / [UIScreen mainScreen].scale;
view = [[UIView alloc] initWithFrame:CGRectMake(0., 0., 320., height)];
view.backgroundColor = UIColorFromRGB(0xC8C7CC);
view.autoresizingMask = UIViewAutoresizingFlexibleWidth;
}
else
{
view = [UIView new];
}
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (IS_OS_VERSION_7 /* && <is this the last section of the data source> */)
{
return 1 / [UIScreen mainScreen].scale;
}
else
{
// This will hide the empty table grid below the cells if they do not cover the entire screen
return 0.01f;
}
}
이것은 나를 위해 문제를 해결했습니다.
확인 clipsToBounds셀에 YES로 설정되어 있지만, NO 셀의 대한 contentView. 또한 설정cell.contentView.backgroundColor = [UIColor clearColor];
이 문제는 많은 상황에서 나타납니다.
저에게는 셀 선택과 관련이 있습니다. 나는 왜 그것을 알지 못하고 너무 깊게 파고들 시간이 없었지만 셀 selectionStyle을 none으로 설정했을 때 발생하기 시작했다고 말할 수 있습니다 . 즉 :
//This line brought up the issue for me
cell.selectionStyle = UITableViewCellSelectionStyleNone;
위의 위임 방법 중 일부를 사용하여 separatorStyle속성을 켜고 끄려고 시도했지만 tableView문제를 해결하기 위해 아무것도하지 않는 것 같습니다.
내가 필요한 이유는 셀 선택이 필요하지 않았기 때문입니다.
그래서 나에게 도움이되는 것을 찾았습니다. 방금 선택을 비활성화했습니다 UITableView.
tableView.allowsSelection = NO;
셀 선택이 필요하지 않은 경우 누군가에게 도움이되기를 바랍니다.
나는 너무 많은 제안을 시도했지만 그것을 고칠 수는 없다. 마침내 나는 다음과 같이 사용자 정의 구분선을 결정했다.
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
var lineView = UIView(frame: CGRectMake(20, cell.contentView.frame.size.height - 1.0, cell.contentView.frame.size.width - 20, 1))
lineView.backgroundColor = UIColor(red: 170.0/255.0, green: 170.0/255.0, blue: 170.0/255.0, alpha: 1)
cell.contentView.addSubview(lineView)
}
P / S : willDisplayCell 에서 사용자 정의 하지 않음 cellForRowAtIndexPath
놀랍게도 셀의 separatorInset값을 앞뒤로 변경하는 것이 효과가있는 것 같습니다.
NSIndexPath *selectedPath = [self.controller.tableView indexPathForSelectedRow];
[self.controller.tableView deselectRowAtIndexPath:selectedPath animated:YES];
UITableViewCell *cell = [self.controller.tableView cellForRowAtIndexPath:selectedPath];
UIEdgeInsets insets = cell.separatorInset;
cell.separatorInset = UIEdgeInsetsMake(0.0, insets.left + 1.0, 0.0, 0.0);
cell.separatorInset = insets;
또한 UITableView의 맨 아래 에이 일관되지 않은 구분선 표시 문제가있었습니다. 사용자 정의 바닥 글보기를 사용하여 비슷한 선을 작성하여 잠재적 인 기존 선 (때로는 누락 된) 위에 표시 할 수있었습니다.
이 솔루션의 유일한 문제는 Apple이 언젠가 선 두께를 변경할 수 있다는 것입니다
- (UIView*) tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
float w = tableView.frame.size.width;
UIView * footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 1)];
footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
footerView.clipsToBounds=NO;
UIView* separatoraddon = [[UIView alloc] initWithFrame:CGRectMake(0, -.5, w, .5)];
separatoraddon.autoresizingMask = UIViewAutoresizingFlexibleWidth;
separatoraddon.backgroundColor = tableView.separatorColor;
[footerView addSubview:separatoraddon];
return footerView;
}
- (CGFloat) tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 1;
}
테이블 뷰 업데이트가 필요한 위치에 다음 코드 줄을 넣는 것을 해결했습니다.
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None;
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine;
예를 들어, 제 경우에는 여기에 넣었습니다.
tableView.beginUpdates()
tableView.insertRowsAtIndexPaths(insertIndexPaths, withRowAnimation: UITableViewRowAnimation.Fade)
tableView.endUpdates()
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None;
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine;
셀 업데이트를 수행하기 전에 셀 선택을 제거해야합니다. 그런 다음 선택을 복원 할 수 있습니다.
NSIndexPath *selectedPath = [self.tableview indexPathForSelectedRow];
[self.tableview deselectRowAtIndexPath:selectedPath animated:NO];
[self.tableview reloadRowsAtIndexPaths:@[ path ] withRowAnimation:UITableViewRowAnimationNone];
[self.tableview selectRowAtIndexPath:selectedPath animated:NO scrollPosition:UITableViewScrollPositionNone];
위의 문제를 해결하려면 viewDidLoad에 빈 바닥 글을 추가하십시오.
UIView *emptyView_ = [[UIView alloc] initWithFrame:CGRectZero];
emptyView_.backgroundColor = [UIColor clearColor];
[tableView setTableFooterView:emptyView_];
viewForFooterInSection 델리게이트 메소드에서 위의 라인을 사용하지 마십시오. 의미 viewForFooterInSection 메소드를 구현하지 않습니다.
에어 포그 답변을 확장하는 데 도움이되지 않았습니다.
높이를 얻으려면 heightforfooter 메서드를 구현해야했습니다.
밝은 회색이 너무 어둡다는 것을 알았습니다. 테이블 뷰의 현재 구분 기호 색상을 잡고 다음을 사용 하여이 문제를 해결했습니다.
UIColor *separatorGray = [self.briefcaseTableView separatorColor]; [footerSeparator setBackgroundColor:separatorGray];
I also ran into this problem in our project. My table view had a tableFooterView which could make this happen. I found the separator below the last row would appear if I removed that tableFooterView.
What made the difference for me was reloading the row for which the bottom separator line would not appear:
NSIndexPath *indexPath =
[NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
I solve this problem in another way: add a layer that its height is 0.5px and its color is lightgray into tableview.tableFooterView as its sublayer.
the code is just like this:
UIView *tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 70)];
CALayer *topSeperatorLine = [CALayer layer];
topSeperatorLine.borderWidth = 0.5f;
topSeperatorLine.borderColor = [UIColor lightGrayColor].CGColor;
topSeperatorLine.frame = CGRectMake(0, 0, 320, 0.5f);
[tableFooterView.layer addSublayer:topSeperatorLine];
self.tableView.tableFooterView = tableFooterView;
In your UITableViewCell Subclass implement layoutSubviews and add:
- (void)layoutSubviews{
[super layoutSubviews]
for (UIView *subview in self.contentView.superview.subviews) {
if ([NSStringFromClass(subview.class) hasSuffix:@"SeparatorView"]) {
CGRect separatorFrame = subview.frame;
separatorFrame.size.width = self.frame.size.width;
subview.frame = separatorFrame;
}
}
}
As someone else mentioned, this problem seems to manifest in a variety of ways. I resolved my issue via the following workaround:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[tableView endUpdates];
Going through the answers and solutions I came up with such observations:
This seems to be problematic in both iOS 7 and 8. I noticed the problem when selecting cell from code in viewDidLoad method so:
1) workaround was doing so in viewDidAppear: if someone doesn't mind the noticeable delay between presenting the view and selecting the cell
2) the second solution worked for me but the code looks a bit fragile as it base on the internal implementation of the UITableViewCell
3) adding own separator seems to be the most flexible and best for now but require more coding :)
Setting the style in viewWillAppear worked for me.
As this is still an issue with IOS 8, I will add my solution in Swift. Set the tableview separator line to none. Then add this code to the cellForRowAtIndexPath delegate method. It will add a nice separator. The if statement allows to decide which cells should have a separator.
var separator:UIView!
if let s = cell.viewWithTag(1000)
{
separator = s
}
else
{
separator = UIView()
separator.tag = 1000
separator.setTranslatesAutoresizingMaskIntoConstraints(false)
cell.addSubview(separator)
// Swiper constraints
var leadingConstraint = NSLayoutConstraint(item: separator, attribute: .Leading, relatedBy: .Equal, toItem: cell, attribute: .Leading, multiplier: 1, constant: 15)
var heightConstraint = NSLayoutConstraint(item: separator, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 0.5)
var bottomConstraint = NSLayoutConstraint(item: cell, attribute: .Bottom, relatedBy: .Equal, toItem: separator, attribute: .Bottom, multiplier: 1, constant:0)
var trailingConstraint = NSLayoutConstraint(item: cell, attribute: .Trailing, relatedBy: .Equal, toItem: separator, attribute: .Trailing, multiplier: 1, constant: 15)
cell.addConstraints([bottomConstraint, leadingConstraint, heightConstraint, trailingConstraint])
}
if indexPath.row == 3
{
separator.backgroundColor = UIColor.clearColor()
}
else
{
separator.backgroundColor = UIColor.blackColor()
}
Here's my solution to this problem. After you insert your cell(s), reload the section. If reloading the entire section is too intensive for you, just reload the indexPaths above and below.
[CATransaction begin];
[CATransaction setCompletionBlock:^{
// Fix for issue where seperators disappear
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
}];
[self.tableView insertRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade];
[CATransaction commit];
ran into a similar problem, I found that another good solution, especially if your dataSource is not large is reload the tableData when you implement the -(void)scrollViewDidScroll:(UIScrollView *)scrollView method, here's an example:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.tableView1) {
[self.tableView1 reloadData];
}
else {
[self.tableView2 reloadData];
}
}
You can also just reload non-visible data based on the visible dataSource, but that requires some more hacking.
Keep in mind this delegate function falls under the UITableViewDelegate protocol!
Hope it helps!
참고URL : https://stackoverflow.com/questions/18924589/uitableviewcell-separator-disappearing-in-ios7
'Programming' 카테고리의 다른 글
| glLoadIdentity ()는 OpenGL에서 무엇을합니까? (0) | 2020.07.02 |
|---|---|
| npm-shrinkwrap.json과 package-lock.json의 차이점은 무엇입니까? (0) | 2020.07.02 |
| 프로토 타입 상속-작성 (0) | 2020.07.02 |
| "R"재료를 검색하는 방법? (0) | 2020.07.02 |
| 이 코드는 sizeof ()를 사용하지 않고 어떻게 배열 크기를 결정합니까? (0) | 2020.07.02 |