iPhone : 기본적으로 UITableView 검색 창 숨기기


85

Interface Builder를 사용하여 테이블보기를 만들었으며 여기에 라이브러리의 검색 표시 줄과 검색 디스플레이 컨트롤러를 추가하여 검색 기능을 추가했습니다. 그러나 IB는 뷰가 처음 표시 될 때 화면 상단에 막대가 표시되도록 설정했습니다.

검색 창을 기본적으로 숨기지 만 테이블보기로 스크롤 할 수있는 방법을 알고 싶습니다 (예는 Apple의 메일 애플리케이션 참조). 나는 전화 해봤 scrollRectToVisible:animated:에서 viewDidLoad테이블 뷰를 아래로 스크롤 할 수 있지만 아무 소용. 기본적으로 검색 창을 숨기는 선호하는 방법은 무엇입니까?

답변:


116

먼저 UITableView의 tableHeaderView에 UISearchBar를 추가하여 테이블의 내용과 함께 스크롤되고 뷰 상단에 고정되지 않도록합니다.

검색 표시 줄은 테이블보기에서 행으로 계산되지 않으므로 테이블보기의 상단을 첫 번째 행으로 스크롤하면 검색 표시 줄이 '숨겨집니다'.

[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

또는 Swift에서 :

yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)

데이터를 포함하기 전에 tableview를 스크롤 scrollToRowAtIndexPath하지 마십시오 (주어진 indexPath가 유효한 행을 가리 키지 않는 경우 (즉, tableview가 비어있는 경우) 예외가 발생 함).


12
실제로 화면을 채울 행이 충분하지 않으면 테이블보기가 스크롤되지 않는 문제가 있습니다. 하나 또는 두 개의 행이있는 테이블에서이 코드는 아무 작업도 수행하지 않습니다. 예상되는 동작입니까? 어떻게 든 주위를 둘러 볼 수 있습니까?
Tim

18
방법을 찾았습니다. 인덱스 경로로 스크롤하는 대신 테이블 스크롤 뷰의 콘텐츠 오프셋을 0.0, 44.0
Tim

107
팀, 그게 갈 길이야! self.tableView.contentOffset = CGPointMake (0, self.searchDisplayController.searchBar.frame.size.height); 사용했습니다.
Joe D' Andrea

1
Btw-[tableView reloadData]를 호출 한 후이 코드를 입력했을 때 내 테이블이 2 행에서 충분한 행으로 이동하여 정상적인 스크롤이 가능하도록 만들었을 때 contentOffset 메서드를 사용하면 검색이 갑자기 표시되고 숨겨지는 것을 발견했습니다. scrollToRowAtIndexPath 메서드를 사용하는 동안 상자는 동일한 멍청함을 갖지 않았습니다.
Chris R

1
이것은 어떤 상황에서도 작동하는 유일한 궁극적 인 방법입니다. contentOffset복잡한 뷰 컨트롤러 레이아웃을 사용하는 경우 값을 설정 하면 중단됩니다. 나는 그것을 추천하지 않는다.
eonil

45

UITableView의 하위보기로 UISearchBar를 추가하지 마십시오. 필요하지 않습니다.

UITableView에는 이에 적합한 tableHeaderView 속성이 있습니다.

- (void) viewDidLoad {
    [super viewDidLoad]; 
    self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
    self.searchBar.showsCancelButton = YES;    
    self.searchBar.delegate = self;
    self.tableView.tableHeaderView = self.searchBar;     
}

기본적으로보고 싶지 않은 경우 :

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView setContentOffset:CGPointMake(0, 44)];
}

다시 숨길 수있는 취소 버튼도 있습니다 .... (키보드 제거)

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
    [self.searchBar resignFirstResponder];
}

저에게는 이것이 HIG와 인라인으로 느껴지는 숨겨진 UISearchBar 구현을 생성 한 유일한 솔루션이었습니다. 테이블보기 상단에 "고정"되어있는 다른 솔루션은 부자연 스럽습니다.
kurtzmarc

1
이 솔루션이 가장 효과적이었습니다. 제 생각에는 이것이 답이되어야합니다.
darwindeeds 2013-08-06

이 솔루션은 훌륭합니다 (+1). 그러나 tableView는 경우에 따라 검색 창을 제대로 숨기지 않습니다 (제 경우 : tableview 컨트롤러가 다른 뷰 컨트롤러에서 뒤로 밀릴 때). 이 문제에 대한 질문이 있습니다. stackoverflow.com/questions/15222186/… 이 질문에 대해 제공된 답변이 좋지 않다고 생각합니다. @bandejapaisa, 당신은 어떤 아이디어가 있습니까?
Brian

3
이것은 나를 위해 잘 작동했지만 전체적으로 44를 하드 코딩하는 대신 viewWillAppear에서 self.tableView.tableHeaderView.frame.size.height를 사용하여 Apple이 향후 검색 창 높이를 변경할 수 있도록하는 것이 좋습니다.
John Stephen

viewWillAppear뷰로 돌아갈 때마다 실행되기 때문에 이것을 넣는 것은 나쁜 생각입니다. 이것은 tableview가 천천히 인치 아래로 내려 간다는 것을 의미합니다. 짜증나는 버그!
사이렌

25

contentOffset은 Tim과 Joe D' Andrea의 의견에 언급되었지만 검색 창을 숨기는 애니메이션을 추가하여 약간 확장되었습니다. 검색 창이 그냥 사라지는 것은 예상치 못한 일이라는 것을 알았습니다.

iOS 4.0 이상을 대상으로하는 사람들을위한 약간의 업데이트를 시도해보십시오.

[UIView animateWithDuration:0.4 animations:^{
    self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
 } completion:nil];

이전 답변 :

[UIView beginAnimations:@"hidesearchbar" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];

self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);

[UIView commitAnimations];


9
애니메이션이이 솔루션의 핵심이라는 것을 알았습니다. 애니메이션없이 콘텐츠 오프셋을 설정하려고하면 아무 작업도 수행되지 않는 것처럼 보입니다. 그러나이 샘플에서 애니메이션 메서드 (또는 블록)를 사용하는 대신 [self.tableView setContentOffset : CGPointMake (0,44) animated : TRUE]를 호출하는 것만으로도 충분합니다.
quickthyme 2011-06-05

애니메이션 없이는 전혀 작동하지 않는 것 같습니다. @quickthyme도 동일한 관찰을했습니다.
Thilo

5
viewDidAppear:대신 에서 구현하면 애니메이션이 필요하지 않고 성공했습니다 viewDidLoad.
wbyoung 2011

8

이 솔루션에 대한 많은 답변이 있지만 나에게 잘 맞는 것은 없습니다.

이것은 완벽하게 작동합니다. 애니메이션이 없으며 수행됩니다.-viewDidLoad

 - (void)viewDidLoad {
     [super viewDidLoad];
     self.tableView.contentOffset = CGPointMake(0,  self.searchBar.frame.size.height - self.tableView.contentOffset.y);
 }

노트 :

코드는 searchBar @property검색 창에 연결된 이 있다고 가정합니다 . 그렇지 않은 경우 self.searchDisplayController.searchBar대신 사용할 수 있습니다.


이것은 나를 위해 일한 유일한 사람입니다! , 그러나 그것은 un viewdidload ... 그래서 처음에는 숨겨졌지만 앱이 실행되는 동안 더 이상 숨겨지지 않습니다. 그리고 나는 그것을 viewwillappear 및 viewdidappear에 넣으려고했지만 잘못 작동합니다. 감사!
fguespe 2014

이상한 @fguespe .. viewDidLoad는 뷰가 인스턴스화 될 때마다 호출되어야합니다. 다른 뷰에서 돌아온 후 UISearchBar가 표시되는 일은 결코 발생하지 않았습니다.
Matej

탭 응용 프로그램을 사용하고 있습니다. 아마도 그럴까요?
fguespe 2014

@fguespe 문제가 될 수 있습니다 흠. 안타깝게도 -viewWillAppear작동하지 않으면 어떻게 해결해야할지 모르겠습니다 . 탭 컨트롤러가보기로 전환 될 때 호출됩니까?
Matej 2014

viewwillappear 및 viewdidappear가 호출되지만 둘 다 시도했는데보기가 잘못 오프셋 된 것과 같습니다. 예상 한 결과를 반환하지 않습니다. 내 말은, 무언가는 있지만 그것은 나쁘다.
fguespe 2014

7

Swift 3 이상

내가 했어:

이것을 선언하십시오 var:

    var searchController = UISearchController()

그리고 viewDidLoad()방법

    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = true
    searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    tableView.contentOffset = CGPoint(x: 0, y: searchController.searchBar.frame.size.height)

5

내 목표는 뷰 컨트롤러가로드 될 때 스토리 보드에서 일반 TableView 스타일의 tableHeaderView에 추가 된 검색 창을 숨기고 사용자가 UITableView 상단에서 아래로 스크롤하면 막대를 표시하는 것이 었습니다. 그래서 저는 Swift를 사용 하고 있으며 확장 기능을 추가했습니다.

extension UITableView {
    func hideSearchBar() {
        if let bar = self.tableHeaderView as? UISearchBar {
            let height = CGRectGetHeight(bar.frame)
            let offset = self.contentOffset.y
            if offset < height {
                self.contentOffset = CGPointMake(0, height)
            }
        }
    }
}

있는 viewDidLoad () 단지 전화 :

self.tableView.hideSearchBar()

5

iOS 가이 상황에서 삽입을 자동으로 조정하기 때문에 tableView를 채우기에 충분한 행이 없을 때 iOS 8에서 모든 기존 솔루션이 작동하지 않습니다. (충분한 행이 있으면 기존 답변이 좋습니다)

이 문제에 6 시간을 낭비한 후 마침내이 솔루션을 얻었습니다.

간단히 말해서, 셀이 충분하지 않으면 빈 셀을 tableView에 삽입해야하므로 tableView의 콘텐츠 크기가 충분히 커서 iOS가 삽입을 조정하지 않습니다.

Swift에서 한 방법은 다음과 같습니다.

1.) 변수 minimumCellNum를 클래스 속성으로 선언

var minimumCellNum: Int?

(2))을 계산 minimumCellNum하고 집합 tableView.contentOffsetviewWillAppear

let screenHeight = Int(UIScreen.mainScreen().bounds.height)

// 101 = Height of Status Bar(20) + Height of Navigation Bar(44) + Height of Tab Bar(49)
// you may need to subtract the height of other custom views from the screenHeight. For example, the height of your section headers.
self.minimumCellNum = (screenHeight - 103 - heightOfOtherCustomView) / heightOfYourCell
self.tableView.contentOffset = CGPointMake(0, 44)

3.) 안으로 tableView(tableView: UITableView, numberOfRowsInSection section: Int))

let numOfYourRows = YOUR LOGIC
if numOfYourRows > minimumCellNum {
    return numOfYourRows
} else {
    return minimumCellNum!
}

4.) selection속성이 인 빈 셀을 None스토리 보드와tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)

if indexPath.row < numOfYourRows {
    return YOUR CUSTOM CELL
} else {
    let cell = tableView.dequeueReusableCellWithIdentifier("EmptyCell", forIndexPath: indexPath) as! UITableViewCell
    return cell
}

5.) 안으로 tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)

if tableView == self.tableView {
    if numOfYourRows < (indexPath.row + 1) {
        return
    }
    YOUR LOGIC OF SELECTING A CELL
}

이것은 완벽한 솔루션은 아니지만 iOS 8에서 실제로 작동하는 유일한 해결 방법입니다. 깔끔한 솔루션이 있는지 알고 싶습니다.


iOS 11에서이 작업을 수행해야했습니다. contentOffset 설정만으로는 0 개 이상의 셀에 대해 iOS 9/10에서 작동했으며 8 개 이상의 셀에 대해 iOS 11에서도 작동했습니다. 덜 필요한 것은이 솔루션입니다. 이유가 있습니까?
Tony

이 게시물의 첫 번째 단락에서 그 이유를 설명한다고 생각합니다.
Brian

나는 첫 번째 단락을 이해했지만, 그것이 나를 위해 iOS 11에서만 "깨졌다"는 것이 여전히 이상했습니다. 셀 수가 같을 때 (충분하지 않음) iOS 9, 10 및 11에서 유사한 동작을 예상했을 것입니다. 다시 한 번 감사 드리며 이전 게시물을 올려 주셔서 죄송합니다!
Tony

4

위의 어느 것도 나를 위해 일하지 않았으므로 누군가가 같은 문제를 겪을 경우를 대비하여.

나는 한 searchBar로 설정 tableHeaderViewiOS7에에 그룹화 된 테이블에. 에서 viewDidLoad내가 가진 tableView.contentOffset = CGPointMake(0, 44);유지하기 위해 searchBar처음에 "숨겨진". 사용자가 아래 searchBar로 스크롤하면 표시됩니다.

목표 : 취소 버튼 탭시 searchBar 숨기기

searchBarCancelButtonClicked(searchBar: UISearchBar!)

이것은 작동하지 않았습니다. [yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; tableView가 너무 많이 스크롤하여 toolBar 뒤에 0 행이 생겼습니다.

작동하지 않음 : tableView.ContentOffset = CGPointMake(0, 44) -아무 일도 일어나지 않습니다.

작동하지 않음 : tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height) -아무 일도 일어나지 않습니다.

이것은 작동하지 않았습니다. tableView.setContentOffset(CGPointMake(0, 44), animated: true); 다시 tableView가 너무 많이 스크롤하여 toolBar 뒤에 0 행이 생겼습니다.

이것은 부분적으로 작동 tableView.setContentOffset(CGPointMake(0, 0) 했지만 titleForHeaderInSectiontoolBar 뒤에서 진행되었습니다.

이 작동 : tableView.setContentOffset(CGPointMake(0, -20)

논리적이지 않은 것처럼 보이지만 -20 만 올바른 위치로 이동했습니다.


당신은 정말로 당신의 포인트를 하드 코딩해서는 안됩니다. 왜 사용하지 CGRectGetHeight(searchBar.bounds)않습니까?
Zorayr

나는 당신이 검색 바의 높이를 얻기 위해 프레임이 설정되지 않은 viewDidLoad () / init ()에서 그것을하고 있어야한다고 생각합니다. 당신이 viewDidLayoutSubviews ()을 시도해야 할 수 있음
Kaushil Ruparelia

tableView가로드를 완료하지 않은 경우 ContentOffset솔루션이 작동 하지 않습니다
Maor

4

콘텐츠 오프셋은가는 길이지만 100 % 작동하지 않습니다.

estimatedRowHeight고정 된 숫자 로 설정하면 작동하지 않습니다 . 아직 해결 방법을 모르겠습니다. 내가 만든 프로젝트 문제 (들)을 보여주는를하고 내가 만든 레이더 애플을.

모든 설정 방법에 대한 신속한 예제를 원한다면 프로젝트를 확인하십시오.


1
감사합니다! 이것이 내가 찾던 것이었다. 위로 올라 가야합니다.
user2387149

3

tableview에 데이터가 없으면 수락 된 답변이 중단됩니다. 그리고 viewDidLoad에 추가하면 특정 상황에서 작동하지 않을 수 있습니다.

[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; // crashes if no rows/data

따라서 대신 다음 코드 줄을 추가하십시오.

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

    [yourTableView setContentOffset:CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)];
}

2

솔직히, 어떤 답변도 실제로 문제를 해결하지 못했습니다. 테이블보기에 행이 없거나 행 높이가 다른 경우이 답변으로는 충분하지 않습니다.

작동하는 유일한 것 :

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.tableView.contentOffset = (CGPoint){.y =  self.tableView.contentOffset.y + self.searchController.searchBar.frame.size.height};
}

오프셋 문제에 대한 좋은 솔루션입니다. UINavigationController를 사용할 때 나를 위해 작동합니다.
Andreas Kraft

1
행 수가 전체 화면을 차지하지 않는 경우 솔루션이 작동하지 않습니다. 이에 대한 해결 방법을 알고 계십니까?
Zorayr

나는 이것을 완전히 이해하지 못합니다. 이것은 테이블에 몇 개의 행이있을 때 나를 위해 작동합니다. 그러나 다음을 사용합니다 self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];..
p0lAris 2015

2

scrollToRowAtIndexPath메서드는 테이블에 행이없는 경우 충돌을 일으 킵니다.

UITableView는 스크롤보기 일 뿐이므로 콘텐츠 오프셋을 간단히 변경할 수 있습니다.

이것은 당신이 당신의 tableHeaderView와 같은 것을 가지고 있는지 확인하고 그것을 숨기기 위해 스크롤한다고 가정합니다.

    if let searchHeight = tableView.tableHeaderView?.frame.height {
        tableView.setContentOffset(CGPoint.init(x: 0, y:searchHeight ), animated: false)
    }

1

tableView가 비어있을 때 "Notes"앱이 항목을 검색 할 수 없음을 발견했습니다. 그래서 -(void)addSubview:(UIView *)view처음에는 빈 테이블을 추가하는 데 사용 하는 것 같습니다. 데이터 소스 배열에 항목을 추가하면 다른 코드를 실행하여 tableView를로드합니다.

그래서 내 해결책은 다음과 같습니다.

if([self.arrayList count] > 0)
{
     [self.tableView reloadData];     //use jdandrea's code to scroll view when cell==nil in cellForRowAtIndexPath
     self.tableView.scrollEnabled = YES;
}
else
{
     tableBlank = [[UITableView alloc]initWithFrame:CGRectMake(0,0,320,416) style:UITableViewStylePlain] autorelease];
     tableBlank.delegate = self;
     tableBlank.dataSource = self;
     [self.view addSubview:tableBlank];
}

도움이 되었기를 바랍니다 :-)


1

tableView의 경계를 변경하면 내부에서 수행 할 수 있으며 viewDidLoad테이블이 비어 있는지 여부에 대해 걱정할 필요가 없습니다 (예외를 피하기 위해).

CGRect newBounds = self.tableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;

사용자가 테이블을 아래로 스크롤하면 검색 창이 나타나고 정상적으로 작동합니다.


1

이 질문에 대한 다른 답변은 전혀 작동하지 않았거나 tableView에 행이 0 개일 때 이상한 동작이 있거나 상위 항목과 중첩 된 항목 사이를 앞뒤로 이동할 때 스크롤 위치를 엉망으로 만들었습니다. 이것은 나를 위해 일했습니다 (목표는로드시 UISearchBar를 숨기는 것입니다).

public override func viewWillAppear(animated: Bool) {        
    if self.tableView.contentOffset.y == 0 {
        self.tableView.contentOffset = CGPoint(x: 0.0, y: self.searchBar.frame.size.height) 
    }
}

설명
언제 tableViewUISearchBar가 표시되면 나타난다이 코드 검사 (의미 볼 y의 위치 contentOffset이며, 일명 스크롤 위치 0). 그렇다면 단순히 searchBar의 높이를 아래로 스크롤합니다. searchBar가 표시되지 않는 경우 (의 더 큰 항목 목록을 생각해 tableView보십시오) tableView중첩 된 광고 항목에서 돌아올 때 위치가 엉망이되므로을 시도하고 스크롤하지 않습니다 .

참고
사항 단일 책임을 보장하고 코드에서 언제든지 호출 할 수있는 재사용 성을 제공하기 위해이 코드를 별도의 메서드에 넣는 것이 좋습니다.


1

표에 항상 하나 이상의 행이있는 경우 표의 첫 번째 행으로 스크롤하면 검색 창이 자동으로 숨겨집니다.

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

self.tableView.selectRowAtIndexPath (firstIndexPath, animated : false, scrollPosition : .Top)

viewDidLoad에 위의 코드를 넣으면 tableView가 아직로드되지 않았기 때문에 오류가 발생하므로 tableView가 이미로드 되었기 때문에 viewDidAppear 에 넣어야합니다 .

viewDidAppear넣으면 tableView를 열 때마다 맨 위로 스크롤됩니다.

UITabBar View Controller이거나 segue를 수행 한 다음 돌아올 때와 같이 tableView가 열려있는 경우이 동작을 원하지 않을 수 있습니다. 초기로드시 맨 위로 스크롤하도록하려면 변수를 만들어 초기로드인지 확인하여 한 번만 맨 위로 스크롤되도록 할 수 있습니다.

먼저 뷰 컨트롤러 클래스에서 isInitialLoad라는 변수를 정의하고 "true"로 설정합니다.

var isInitialLoad = true

그런 다음 viewDidAppear 에서 isInitialLoad가 true인지 확인 하고 true이면 맨 위로 스크롤하여 isInitialLoad 변수를 false로 설정합니다.

if isInitialLoad {
            let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
            self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)

            isInitialLoad = false
        }

1

아래 코드는 나를 위해 일하고 있습니다.

self.tableView.contentOffset = CGPointMake(0.0, 44.0);

1

콘텐츠 오프셋 및 scrollToIndexpath 설정을 시도했지만 만족스럽게 작동하지 않았습니다. viewDidLoad에서 searchBar로 tableHeaderView 설정을 제거하고 아래와 같이 scrollview delegate에 설정했습니다.

override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
    if scrollView.contentOffset.y < 0 && tableView.tableHeaderView == nil {
        tableView.tableHeaderView = searchController.searchBar
        tableView.setContentOffset(CGPointMake(0, scrollView.contentOffset.y + searchController.searchBar.frame.size.height), animated: false)
    }
}

이것은 마치 매력처럼 작동했습니다. 콘텐츠 오프셋 설정은 부드러운 스크롤을위한 것입니다.


0

상태 표시 줄탐색 표시 줄 을 고려 하는 것을 잊지 마십시오 . 내 테이블 뷰 컨트롤러는 탐색 컨트롤러에 포함되어 있습니다 viewDidAppear.

tableView.contentOffset = CGPointMake(0, -20) // -20 = 44 (search bar height) - 20 (status bar height) - 44 (navigation bar height)

나를 위해 일했습니다.


0

Swift의 경우 :

검색 창의 높이와 같아야하는 tableview 콘텐츠 y 오프셋을 만드세요.

self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height)

0

스위프트 3

빈 테이블에서도 작동합니다!

내 환경에서는 xib 파일로 사용자 지정 셀을로드하고 rowHeight는 자동으로 설정됩니다.

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        self.tableView.contentOffset = CGPoint(x: 0, y: self.tableView.contentOffset.y + self.searchController.searchBar.bounds.height)
}

0

비슷한 문제가있었습니다. 이 문제를 해결하기 위해 찾은 유일한 방법은 UITableView contentOffset 속성에서 키 값 관찰자를 사용하는 것입니다.

일부 디버깅 후 테이블보기 내용 크기가 tableview보다 작은 경우 문제가 발생한다는 것을 깨달았습니다. viewWillAppear에서 KVO를 시작합니다. 그리고보기가 나타난 후 0.3 초 ​​후에 KVO를 중지합니다. contentOffset이 0.0이 될 때마다 KVO는 반응하고 검색 창 높이에 contentOffset을 설정합니다. 보기 레이아웃이보기가 나타난 후에도 contentOffset을 재설정하기 때문에 0.3 초 ​​후에 비동기식 KVO를 중지합니다.

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  [self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}

-(void)viewDidAppear:(BOOL)animated{
   __weak typeof (self) weakSelf = self;
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [weakSelf.tableView removeObserver:self forKeyPath:@"contentOffset"];});
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"contentOffset"] && self.tableView.contentOffset.y == 0.0) {
       self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.tableView.tableHeaderView.frame));
    }
}

-(void)dealloc {
    [self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.