ios - 시뮬레이터 - xcode 팁




iOS 8 UITableView separator inset 0 작동하지 않음 (20)

Swift 2.0 확장

난 그냥 tableview 셀 구분 기호에서 여백을 제거하기 위해 만든 확장을 공유 싶었어요.

extension UITableViewCell {
    func removeMargins() {

        if self.respondsToSelector("setSeparatorInset:") {
            self.separatorInset = UIEdgeInsetsZero
        }

        if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
            self.preservesSuperviewLayoutMargins = false
        }

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

문맥에서 사용 :

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    cell.removeMargins()
    return cell

UITableView 의 구분 기호 인세 트가 사용자 정의 값으로 설정되는 응용 프로그램이 있습니다 - 오른쪽 0 , 왼쪽 0 . 이것은 iOS 7.x 에서 완벽하게 작동하지만 iOS 8.0 에서는 분리 자 삽입이 오른쪽에서 기본값 인 15 설정되어 있습니다. xib 파일에서 0 설정하더라도 여전히 잘못 표시됩니다.

UITableViewCell 분리 자 마진을 제거하려면 어떻게합니까?


많은 조사 끝에 ...

여기에이 물건들을 완전히 제어 할 수있는 유일한 방법이있다.

각 셀의 구분 기호 및 레이아웃 여백을 완벽하게 제어합니다. UITableviewDelegatewillDisplayCell 메소드에서이를 수행하십시오.

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.layoutMargins = UIEdgeInsetsZero
    cell.contentView.layoutMargins = UIEdgeInsetsMake(0, 10, 0, 10)
    cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
}

셀 객체는 구분 기호를 제어하고 contentView 는 다른 모든 것을 제어합니다. 구분 기호 인세 트 공간이 예기치 않은 색상으로 나타나면 해결해야합니다.

cell.backgroundColor = cell.contentView.backgroundColor

3 층에서 해답을 본 후에 TableView와 TableViewCell 사이에 구분 기호를 설정하고 몇 가지 테스트를 수행 한 관계를 파악하려고했습니다. 내 결론은 다음과 같습니다.

  1. 우리는 셀의 구분 기호를 0으로 설정하는 것이 분리 기호를 두 단계로 이동시켜야한다고 생각할 수 있습니다. 첫 번째 단계는 셀의 separatorinset 을 0으로 설정하는 것입니다. 두 번째 단계는 셀의 marginlayout 을 0으로 설정하는 것입니다.

  2. TableView의 separatorinset을 설정하면 marginlayout 이 셀의 separatorinset에 영향을 줄 수 있습니다. 그러나 테스트에서 TableView의 separatorinset 은 쓸모없는 것처럼 보입니다. TableView의 marginlayout 은 실제로 셀의 marginlayout에 영향을 줄 수 있습니다.

  3. Cell의 PreservesSuperviewLayoutMargins = false를 설정하면 셀에서 TableView의 여백 조정 효과를 차단할 수 있습니다.

  4. 솔루션 중 하나 :

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
    
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero
    
        return cell
    }
    

Arg !!! Cell 하위 클래스에서이 작업을 수행 한 후 다음 작업을 수행하십시오.

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

또는 cell.layoutMargins = UIEdgeInsetsZero; 설정 cell.layoutMargins = UIEdgeInsetsZero; 나를 위해 그것을 고쳤다.


cdstamper가 테이블 뷰 대신 제안한 것과 관련하여 셀의 layoutSubview 메서드 아래에 아래 라인을 추가하면 저에게 적합합니다.

- (void)layoutSubviews 
{
    [super layoutSubviews];

    if ([self respondsToSelector:@selector(setSeparatorInset:)])
                [self setSeparatorInset:UIEdgeInsetsZero];

        if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
        {
            [self setPreservesSuperviewLayoutMargins:NO];;
        }

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

iOS 9의 경우 다음을 추가해야합니다.

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

자세한 내용은 question 참조하십시오.


가장 득표 한 답변보다 더 컴팩트 한 방법으로 ...

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

    if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
         [cell setSeparatorInset:UIEdgeInsetsZero];
         [cell setPreservesSuperviewLayoutMargins:NO];
         [cell setLayoutMargins:UIEdgeInsetsZero];
    }

}


나는 이것을 이렇게함으로써 일하게했다 :

tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;

나를 위해 단순한 선이 그 일을했다.

cell.layoutMargins = UIEdgeInsetsZero

다음은 인서트를 전역 적으로 제거하는 쉬운 방법입니다.

UITableViewCell+Extensions.swift :

import UIKit

extension UITableViewCell {

  override public var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set { }
  }

}

AppDelegate application:didFinishLaunchingWithOptions: :

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

a) 확장에서 separatorInset 을 그냥 오버라이드하거나 b) layoutMargins 의 외양 프록시를 대신 설정할 수도 있습니다. 둘 다 작동하지 않습니다. separatorInset 이 속성으로 표시 되더라도 속성 (또는 메서드)으로 재정의하려고하면 컴파일러 오류가 발생합니다. 그리고 UITableViewCelllayoutMargins 대한 모양 프록시 설정 (또는 UITableViewlayoutMarginsseparatorInset 대한 모양 프록시 설정)은 아무 효과가 없습니다.


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

디버거에서 주위를 잠깐 살펴보면 구분선이 UITableViewCell 하위 뷰라는 것을 알 수 있습니다. 셀 자체가이 선의 레이아웃에 대해 상당한 책임을지고있는 것처럼 보입니다.

iOS 8에는 레이아웃 여백 의 개념이 도입되었습니다. 기본적으로보기의 레이아웃 여백은 모든면에서 8pt 이며 조상보기에서 상속 됩니다.

UITableViewCell 은 분리 선을 배치 할 때 왼쪽 여백을 존중하도록 선택하여 왼쪽 여백을 제한합니다.

원하는 것을 모두 얻으려면 모두 함께해야합니다.

  • 왼쪽 레이아웃 여백을 0 설정합니다.
  • 상속 된 마진을 모두 무시하십시오.

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

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

주의 사항 :

  • 이 코드는 셀마다 한 번만 실행하면되고 (셀의 속성을 구성하는 것뿐입니다), 실행을 선택하면 아무 것도 특별하지 않습니다. 당신에게 가장 깨끗한 것처럼 보이십시오.
  • 안타깝게도 Interface Builder에서 구성 할 수있는 속성은 없지만 원할 경우 SuperviewLayoutMargins를 preservesSuperviewLayoutMargins 하기위한 사용자 정의 런타임 속성을 지정할 수 있습니다.
  • 분명히 앱이 이전 OS 출시를 목표로한다면 iOS 8 이상에서 실행될 때까지 위 코드를 실행하지 않아야합니다.
  • preservesSuperviewLayoutMargins 설정하는 대신 조상보기 (예 : 표)에 0 왼쪽 여백이 있도록 구성 할 있지만 전체 계층 구조를 제어하지 않으면 본질적으로 오류가 발생하기 쉽습니다.
  • 왼쪽 여백 만 0 으로 설정하고 나머지는 그대로두면 아마 약간 더 깨끗합니다.
  • UITableView 가 일반 스타일 테이블의 맨 아래에 UITableView 는 "추가"구분 기호에 0 개의 인세 트가 필요한 경우 테이블 수준에서 동일한 설정을 지정해야합니다 (이 중 하나를 시도하지 않았습니다).

빠른:

override func viewDidLoad() {
    super.viewDidLoad()

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

    self.tableView.layoutIfNeeded()            // <--- this do the magic
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     ...

    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }

    return cell
}

셀을 스크롤 할 때마다 ( willDisplayCell 사용하여) preservesSuperviewLayoutMarginslayoutMargins 를 업데이트하는 대신 cellForRowAtIndexPath: 에서 한 번 수행하도록 제안합니다.

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}

스위프트에서 루카스 대답 :

    // iOS 7:
    UITableView.appearance().separatorStyle = .SingleLine
    UITableView.appearance().separatorInset = UIEdgeInsetsZero
    UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

    // iOS 8:
    if UITableView.instancesRespondToSelector("setLayoutMargins:") {
        UITableView.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
    }

아래의 코드 스 니펫을 사용하면 IOS 8 & 7의 UITableView에 대해 원하지 않는 패딩 문제를 피할 수 있습니다.

-(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];
    }
}

응용 프로그램 시작시 (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의 코드를 깨끗하게 유지할 수 있으며 원하는 경우 항상 재정의 할 수 있습니다.


이것이 나의 해결책이다. 이것은 사용자 정의 셀 서브 클래스에 적용되며 서브 클래스에 두 셀을 추가하기 만하면됩니다.

  1. - (UIEdgeInsets)layoutMargins {    
        return UIEdgeInsetsMake(0, 10, 0, 10);
    }
    

2.

self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);

그리고 디자이너에게 당신을 위해 하나를 그려달라고 요청하지 않고도 구분 기호의 위치를 ​​사용자 정의 할 수 있습니다 ..........


Swift 3.0 예 :

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // removing seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // prevent the cell from inheriting the tableView's margin settings
    if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // explicitly setting cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

이 스 니펫을 추가하면 iOS8에서 Swift의 우아한 작품이 나에게 적합하다. :)

    // tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero
}

이것은 iOS 8 및 iOS 9에서 완벽하게 작동했습니다.

대한 OBJ-C

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(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];
        }
         return cell;
    }




ios8