[ios] iOS 8 UITableView 구분 기호 삽입 0이 작동하지 않습니다

UITableView구분 기호 삽입이 사용자 정의 값-오른쪽 0, 왼쪽으로 설정된 앱이 0있습니다. 이것은 완벽하게 작동 iOS 7.x하지만 iOS 8.0구분 기호 삽입이 15오른쪽 의 기본값으로 설정되어 있음 을 알 수 있습니다. xib 파일에서로 설정 0되었지만 여전히 잘못 표시됩니다.

UITableViewCell구분자 여백을 어떻게 제거 합니까?



답변

iOS 8.0에서는 셀 및 테이블보기에 layoutMargins 속성이 도입되었습니다.

이 속성은 iOS 7.0에서 사용할 수 없으므로 할당하기 전에 확인해야합니다!

쉬운 수정은 셀을 서브 클래 싱하고 @ user3570727에서 제안한대로 레이아웃 여백 속성을 재정의하는 것입니다. 그러나 안전 영역에서 여백을 상속하는 것과 같은 시스템 동작이 손실되므로 아래 해결책을 권장하지 않습니다.

(목표 C)

-(UIEdgeInsets)layoutMargins {
     return UIEdgeInsetsZero // override any margins inc. safe area
}

(빠른 4.2) :

override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }

속성을 무시하지 않거나 조건부로 설정해야하는 경우 계속 읽으십시오.


layoutMargins속성 외에도 Apple은 셀에 속성 을 추가 하여 테이블 뷰의 여백 설정을 상속하지 못하게합니다. 이 특성을 설정하면 셀이 테이블보기와 독립적으로 자체 여백을 구성 할 수 있습니다. 그것을 재정의로 생각하십시오.

이 속성이라고 preservesSuperviewLayoutMargins하고, 그것을 설정하면 NO셀의 수 layoutMargin대로 재정의 설정을 layoutMargin사용자의 TableView에 설정됩니다. 둘 다 시간을 절약 하고 (테이블 뷰의 설정을 수정할 필요가 없음 ) 더 간결합니다. 자세한 설명은 Mike Abdullah의 답변을 참조하십시오.

참고 : 다음은 Mike Abdullah의 답변에 표시된 것처럼 셀 수준 여백 설정에 대한 깨끗한 구현입니다 . 셀을 설정하면 preservesSuperviewLayoutMargins=NO테이블 뷰가 셀 설정을 무시하지 않습니다. 실제로 전체 테이블 뷰가 일정한 마진을 갖기를 원한다면 이에 따라 코드를 조정하십시오.

셀 여백을 설정하십시오.

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Remove seperator inset
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
           [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

스위프트 4 :

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Remove seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // Prevent the cell from inheriting the Table View's margin settings
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // Explictly set your cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

설정 preservesSuperviewLayoutMarginsNO로 셀 재산은 해야 휴대 여백을 무시에서 테이블보기를 방지합니다. 경우에 따라 제대로 작동하지 않는 것 같습니다.

모두 실패하면 테이블 뷰 여백을 무차별하게 적용 할 수 있습니다.

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView setLayoutMargins:UIEdgeInsetsZero];
    }
} 

스위프트 4 :

func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // Force your tableview margins (this may be a bad idea)
    if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
        tableView.separatorInset = .zero
    }
    if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
        tableView.layoutMargins = .zero
    }
}

… 그리고 당신은 간다! iOS 7 및 8에서 작동합니다.


편집 : 모하메드 살레 내 관심을 아이폰 OS 9에서 가능한 변화를 가져왔다 당신은 테이블보기의 설정해야 할 수도 있습니다 cellLayoutMarginsFollowReadableWidth에를NO 당신이 세트 또는 여백을 사용자 정의하려는 경우입니다. 마일리지가 다를 수 있지만이 문서는 잘 설명되어 있지 않습니다.

이 속성은 iOS 9에만 존재하므로 설정하기 전에 확인하십시오.

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

스위프트 4 :

if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
    myTableView.cellLayoutMarginsFollowReadableWidth = false
}

( iOS 8 UITableView 구분 기호 삽입 0 코드가 작동하지 않음 )

편집 : 다음은 순수한 인터페이스 빌더 접근법입니다.

TableViewAttributesInspector
TableViewCellSizeInspector

참고 : iOS 11 은이 동작의 많은 부분을 변경하고 단순화합니다. 업데이트가 곧 나올 것입니다 …


답변

아가 !!! Cell서브 클래스 에서이 작업을 수행 한 후 :

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

또는 cell.layoutMargins = UIEdgeInsetsZero;나를 위해 고정을 설정하십시오 .


답변

문제를 해결하기 위해 맹목적으로 충전하기 전에 잠시 시간을내어 문제를 이해합시다.

디버거에서 빠르게 찌르면 구분선이 하위 뷰임을 알 수 있습니다. UITableViewCell . 셀 자체는 이러한 라인의 레이아웃에 대해 상당한 책임이있는 것으로 보입니다.

iOS 8은 레이아웃 마진 개념을 도입했습니다 . 기본적으로 뷰의 레이아웃 여백은 8pt모든면에 있으며 조상 뷰에서 상속 됩니다.

가장 잘 알 수 있듯이 구분선을 UITableViewCell배치 할 때 왼쪽 삽입 여백을 사용하여 왼쪽 레이아웃 여백을 존중하도록 선택합니다.

이 모든 것을 종합하여 원하는 제로의 시작을 달성하려면 다음이 필요합니다.

  • 왼쪽 레이아웃 여백을 0
  • 상속 된 여백을 무시하고

그렇게하면 달성하기가 매우 간단한 작업입니다.

cell.layoutMargins = UIEdgeInsetsZero;
cell.preservesSuperviewLayoutMargins = NO;

참고 사항 :

  • 이 코드 셀당 (방금 결국 셀의 속성을 구성하고) 일단 실행하고, 아무것도 특별한 당신이 그것을 실행하도록 선택하면에 대해이있다. 당신에게 가장 깨끗한 것처럼 행동하십시오.
  • 안타깝게도 Interface Builder에서 구성 할 수있는 속성은 없지만 preservesSuperviewLayoutMargins원하는 경우 사용자 정의 런타임 속성을 지정할 수 있습니다 .
  • 분명히 앱이 이전 OS 릴리스를 대상으로하는 경우 iOS 8 이상에서 실행될 때까지 위 코드를 실행하지 않아야합니다.
  • 오히려 설정보다 preservesSuperviewLayoutMargins, 당신은 할 수 있습니다 (예 : 테이블 등) 조상 뷰를 가지고 구성 0도 왼쪽 여백을,하지만 당신은 그 전체 계층 구조를 제어하지 않는 한이 본질적으로 오류가 발생하기 쉬운 것 같다.
  • 왼쪽 여백 만 설정 0하고 나머지는 그대로 두는 것이 약간 더 깨끗할 것입니다 .
  • UITableView일반 스타일 테이블의 맨 아래에 그려진 “추가”구분 기호에 0 삽입을 원한다면 테이블 수준에서 동일한 설정을 지정해야한다고 생각합니다 (이 시도하지 않았습니다!)

답변

나는 이것이 내가 여기에서 물었던 것과 같은 질문이라고 믿는다 : XCode 6 iPhone Simulator 용 iOS 8 UITableView에서 SeparatorInset 제거

에서 아이폰 OS 8 에서 상속하는 모든 객체에 대한 하나 개의 새로운 특성이있다 UIView. 그래서, 해결책은SeparatorInset iOS 7.x에서 은 iOS 8의 UITableView에 표시되는 공백을 제거 할 수 없습니다.

새 속성을 ” layoutMargins “라고합니다.

@property(nonatomic) UIEdgeInsets layoutMargins
Description   The default spacing to use when laying out content in the view.
Availability  iOS (8.0 and later)
Declared In   UIView.h
Reference UIView Class Reference

iOS 8 UITableView setSeparatorInset : UIEdgeInsetsZero setLayoutMargins : UIEdgeInsetsZero

해결책:-

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [tableView setLayoutMargins:UIEdgeInsetsZero];
    }

   if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
   }
}

존재 cell.layoutMargins = UIEdgeInsetsZero;여부를 확인하지 않고 설정 하면 layoutMarginsiOS 7.x에서 앱이 중단됩니다. 따라서 가장 좋은 방법은 layoutMargins먼저 존재 하는지 확인하는 것 setLayoutMargins:UIEdgeInsetsZero입니다.


답변

응용 프로그램 시작시 (UI가로드되기 전에) UIAppearance를 한 번 사용하여 기본 전역 설정으로 설정할 수 있습니다.

// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];

[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {

    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];

}

이렇게하면 UIViewController의 코드를 깨끗하게 유지하고 원하는 경우 항상 재정의 할 수 있습니다.


답변

iOS는 셀 및 테이블 뷰에 layoutMargins 속성을 도입했습니다.

이 속성은 iOS 7.0에서 사용할 수 없으므로 할당하기 전에 확인해야합니다!

그러나 Apple은 테이블 뷰의 여백 설정을 상속하지 못하게하는 preservesSuperviewLayoutMargins 라는 속성 을 셀에 추가했습니다 . 이렇게하면 셀이 테이블보기와 독립적으로 자체 여백을 구성 할 수 있습니다. 그것을 재정의로 생각하십시오.

이 속성을 preservesSuperviewLayoutMargins 라고 하며 NO로 설정하면 테이블 뷰의 layoutMargin 설정을 사용자의 셀 layoutMargin 설정으로 대체 할 수 있습니다. 둘 다 시간을 절약 하고 (테이블 뷰의 설정을 수정할 필요가 없음 ) 더 간결합니다. 자세한 설명은 Mike Abdullah의 답변을 참조하십시오.

참고 : Mike Abdullah의 답변에 표시된 것처럼 적절하고 덜 지저분한 구현입니다. 셀의 preservesSuperviewLayoutMargins = NO를 설정하면 테이블 뷰가 셀 설정을 무시하지 않습니다.

첫 번째 단계-셀 여백 설정 :

/*
    Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath)
{
    // Remove separator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }

    // Explictly set your cell's layout margins
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

NO로 세포에 preservesSuperviewLayoutMargins 속성을 설정 해야 휴대 여백을 무시에서 테이블보기를 방지합니다. 경우에 따라 제대로 작동하지 않는 것 같습니다.

두 번째 단계-모두 실패한 경우에만 테이블 뷰 여백을 무차별 적용 할 수 있습니다.

/*
    Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Force your tableview margins (this may be a bad idea)
    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }

    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }
}

… 그리고 당신은 간다! iOS 7은 물론 iOS 7에서도 작동합니다.

참고 : iOS 8.1 및 7.1을 사용하여 테스트했지만 필자의 경우이 설명의 첫 단계 만 사용하면됩니다.

두 번째 단계는 렌더링 된 셀 아래에 채워지지 않은 셀이있는 경우에만 필요합니다. 테이블이 테이블 모델의 행 수보다 큰 경우 두 번째 단계를 수행하지 않으면 분리기 오프셋이 달라집니다.


답변

Swift에서는 layoutMargins속성 이기 때문에 약간 더 성가 시므로 getter setter 를 재정의해야합니다 .

override var layoutMargins: UIEdgeInsets {
  get { return UIEdgeInsetsZero }
  set(newVal) {}
}

이것은 효과적으로 layoutMargins읽기 전용을 만들 것이며 , 제 경우에는 괜찮습니다.