Programing

UITableView는 반투명 탐색 모음 아래에 있습니다.

lottogame 2020. 12. 14. 07:46
반응형

UITableView는 반투명 탐색 모음 아래에 있습니다.


IOS 7 앱에서 투명한 탐색 표시 줄을 사용하려고합니다. 내 응용 프로그램에 전체 화면 이미지가 있습니다. 또한 해당 이미지 위에 UITableView가 있습니다. 아래 코드를 사용하면 이미지가 원하는대로 화면에 맞지만 UITableView는 탐색 모음 아래에 있습니다.

viewDidLoad

나는 사용한다

self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
self.navigationController.view.backgroundColor = [UIColor clearColor];

로 변경하면 self.navigationController.navigationBar.translucent = NO;괜찮지 만 탐색 모음에서 투명도를 잃습니다.


tableView의 contentInsets를 설정할 수 있으므로 처음에는 탐색 모음 아래에 있지만 그 뒤로 스크롤됩니다 (콘텐츠가 겹침).

self.tableView.contentInset = UIEdgeInsetsMake(44,0,0,0);

또는 테이블 뷰의 프레임을 오프셋 할 수 있습니다. 그런 다음 스크롤링 콘텐츠가 내비게이션 바 아래에서 잘릴 것입니다.


내 사례가 도움이되었습니다 (Bill Chan의 코드 수정 버전).

Objective C 버전 :

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];   
    CGRect rect = self.navigationController.navigationBar.frame;
    float y = rect.size.height + rect.origin.y;
    self.tableView.contentInset = UIEdgeInsetsMake(y, 0, 0, 0);
}

요점은 navigationBar ( rect.size.height) 의 높이 와 상태 표시 줄의 높이 ( rect.origin.y)를 위해 테이블을 아래로 밀어야한다는 것입니다 .

Swift 버전 (Swift 2 와도 호환) :

override func viewDidLayoutSubviews() {
    if let rect = self.navigationController?.navigationBar.frame {
        let y = rect.size.height + rect.origin.y
        self.tableView.contentInset = UIEdgeInsetsMake( y, 0, 0, 0)
    }
}

iOS 9에서도 비슷한 문제가 발생했습니다. viewController를 처음 열면 tableView가 상단 표시 줄 아래에 있습니다. tableView를 스크롤 한 후 모든 것이 잘 작동합니다.

  1. 보기 컨트롤러 선택
  2. 'Attributes Inspector'탭을 클릭합니다.
  3. 'Under Top Bars'를 선택 취소하십시오.

여기에 이미지 설명 입력


상태 막대의 탐색 줄 더한 높이의 높이의 tableview의 y 위치를 설정 (내버려 height)

즉,

  height = 64; // height of navigation bar = 44(In portait), height of status bar = 20
  tableView.frame = CGRectMake(tableView.frame.origin.x, height , tableView.frame.size.width, tableView.frame.size.height);

자동 레이아웃을 사용하는 경우 프레임을 변경하는 대신 tableView 상단 제약 조건을 업데이트하십시오.

또한 viewController를 automaticAdjustsScrollViewInsets를 NO로 변경하십시오.

self.automaticallyAdjustsScrollViewInsets =  NO;

가로 모드의 탐색 모음 높이가 32이기 때문에 다른 방향 업데이트 프레임 및 contentInset을 (52)로 지원하는 경우.

샘플 확인


이것은 iOS8의 가로 모드와 세로 모드에서 모두 작동합니다.

- (void)viewDidLayoutSubviews
{
  [super viewDidLayoutSubviews];

  CGRect rect = self.navigationController.navigationBar.frame;

  float y = -rect.origin.y;

  self.tableView.contentInset = UIEdgeInsetsMake(y ,0,0,0);
}

장치의 방향을 기반으로 할 수 있으므로 삽입 값을 하드 코딩하지 않는 것이 좋습니다.

암호:

func setTableViewContentInset() {

    let contentInsetHeight = topLayoutGuide.length
    let contentInset = UIEdgeInsetsMake(contentInsetHeight, 0, 0, 0)

    tableView.contentInset = contentInset
    tableView.scrollIndicatorInsets = contentInset
}

func scrollToTop() {

    if tableView.indexPathsForVisibleRows?.count > 0 {

        let topIndexPath = NSIndexPath(forRow: 0, inSection: 0)

        tableView.scrollToRowAtIndexPath(topIndexPath, atScrollPosition: .Top, animated: false)
    }
}

func scrollToTopOfVisibleCells() {

    if let visibleIndexPaths = tableView.indexPathsForVisibleRows where tableView.indexPathsForVisibleRows?.count > 0 {

        let topMostVisibleIndexPath = visibleIndexPaths[0]

        tableView.scrollToRowAtIndexPath(topMostVisibleIndexPath, atScrollPosition: .Top, animated: false)

    }        
}

//MARK: Load Views
override func viewDidLoad() {
    super.viewDidLoad()

    setTableViewContentInset()
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    scrollToTop()
}

//MARK: Trait collection change
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    setTableViewContentInset()
    scrollToTopOfVisibleCells()
}

대부분의 경우 매직 상수를 도입하는 솔루션은 확장되지 않습니다. 예를 들어 다음 iPhone에서 다른 탐색 막대 높이를 도입하면 코드를 업데이트해야합니다.

다행스럽게도 Apple은이 문제를 극복 할 수있는 깨끗한 방법을 제공했습니다 (예 : topLayoutGuide) .

topLayoutGuide 속성은 뷰 컨트롤러가 화면의 맨 앞에있을 때 작동합니다. 반투명하거나 투명한 UIKit 막대 (예 : 상태 또는 탐색 막대) 뒤에 표시하지 않으려는 콘텐츠의 최대 수직 범위를 나타냅니다.

프로그래밍 방식으로 다음 코드 스 니펫을 사용하여 달성 할 수 있습니다 (IB를 통해서도 동일하게 달성 할 수 있음).

override func viewDidLoad() {
  super.viewDidLoad()

  automaticallyAdjustsScrollViewInsets = false
  tableView.translatesAutoresizingMaskIntoConstraints = false
  NSLayoutConstraint.activate([
    tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
    tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
    tableView.topAnchor.constraint(equalTo: 
       topLayoutGuide.bottomAnchor),
    tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
  ])
}

참고 : topLayoutGuide는 iOS 11에서 더 이상 사용되지 않으므로 대신 UIView safeAreaLayoutGuide 속성을 사용해야합니다 .


소개

나는 iOS 개발과 Stack Overflow를 처음 사용하므로 내 게시물이 완벽하지 않은 경우 용서하십시오.

나는 또한이 문제가 있었고 UITableView에 대한 콘텐츠 삽입을 사용했을 때 처음로드하거나 다른 탭에서 방문했을 때 완벽하게 작동했습니다. 그러나 뷰로 다시 이동하면 추가 "패딩"이 생깁니다. UITableView가 매번 올바르게 배치되도록 해결 방법을 찾았습니다.

문제

UITableView 또는 탭을 처음로드 할 때 탐색 모음 아래의 테이블을 올바르게 시작하려면 삽입이 필요하지만 뒤로 탐색 할 때는 삽입이 필요하지 않습니다. 어떤 이유로 든 위치를 올바르게 계산하기 때문입니다. UITableView. 이것이 여분의 패딩을 얻을 수있는 이유입니다.

해결책

이 솔루션은 부울을 사용하여 멀리 이동했는지 여부를 확인하여 콘텐츠 삽입이 필요한지 여부를 올바르게 결정할 수 있습니다.

에서 -(void)viewDidLoad나는 설정 hasNavigatedFurther = NO. 그때:

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (!hasNavigatedFurther) {
        self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
    } else {
        self.tableView.contentInset = UIEdgeInsetsZero;
        //In order to allow visiting between tabs and retaining desired look
        hasNavigatedFurther = NO;
    }
}

이 작업 hasNavigatedFurther = YES을 수행하려면 탐색 스택에 다른 뷰를 푸시하는 코드 바로 앞에 설정해야합니다 .

-(void)btnTouched:(id)sender {
    hasNavigatedFurther = YES;
    NextViewController* nvc = [NextViewController new];
    [self.navigationController pushViewController:nvc animated:YES];
}

처음으로 뷰 컨트롤러를 contentInset탐색 할 때 상단 셀의 패딩을 고려하여 내비게이션 막대의 높이에 맞게 테이블 뷰를 조정하는 다음 솔루션을 생각해 냈습니다 . 스택에 다른 뷰 컨트롤러를 누른 후, 뷰 컨트롤러에 반환 할 때, I는 다음을 재조정 contentInset한다 UIEdgeInsetsZero:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self adjustEdgeInsetsForTableView];
}

- (void)adjustEdgeInsetsForTableView {
    if(self.isMovingToParentViewController) {
        self.tableViewForm.contentInset = UIEdgeInsetsMake(self.navigationController.navigationBar.frame.size.height + padding, 0, 0, 0);
    } else {
        self.tableViewForm.contentInset = UIEdgeInsetsZero;
    }
}

이 코드 만 문제를 해결합니다.

  @IBOutlet weak var tableView: UITableView!

  func viewDidLoad() {
      super.viewDidLoad()
      self.tableView.contentInset = UIEdgeInsetsZero
  }

I combined @Adam Farrell and @Tash Pemhiwa 's solutions, and finally the code below works for me:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self adjustEdgeInsetsForTableView];
}



- (void)adjustEdgeInsetsForTableView
{
    if(self.isMovingToParentViewController) {
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    } else {
        self.tableView.contentInset = UIEdgeInsetsMake(64, 0, 0, 0);
    }
}

Hope this will help people who waste couple of hours on this weird UI behavior.


Constrain the table view to the bottom of the navigation bar. The table view will automatically be offset by 44, but then in code we can just do this:

tableView.contentInset = UIEdgeInsets(top: -44, left: 0, bottom: 0, right: 0)

The bar is transparent and has no color, but the table view does not overlap it at all. Notice the word "Hook" gets cut off despite the navigation bar being transparent. This will only work of you constrain the table view top edge to be 0 from the navigation bar. NOT 0 from the top view.

여기에 이미지 설명 입력


try to use layoutguide to fix

var constraints = [NSLayoutConstraint]()   
let guide = view.safeAreaLayoutGuide
            constraints.append(self.tableView.leadingAnchor.constraint(equalTo: guide.leadingAnchor))
            constraints.append(self.tableView.trailingAnchor.constraint(equalTo: guide.trailingAnchor))
            constraints.append(self.tableView.topAnchor.constraint(equalTo: guide.topAnchor))
            constraints.append(self.tableView.bottomAnchor.constraint(equalTo: guide.bottomAnchor))

All you need is love this:

assert(tableView.contentInsetAdjustmentBehavior == .automatic)

there is zero need to do ugly magic constants beardance from iOS 11 onwards

navbar 언더 랩을 수정하기 위해 contentInsetAdjustmentBehavior를 .none으로 설정할 필요조차 없었습니다.

.automatic

자동으로 작동

참고 URL : https://stackoverflow.com/questions/24468831/uitableview-goes-under-translucent-navigation-bar

반응형