iPhone: Ẩn thanh tìm kiếm UITableView theo mặc định


85

Tôi đã sử dụng Trình tạo giao diện để tạo chế độ xem bảng, vào đó tôi đã thêm Thanh tìm kiếm và Bộ điều khiển hiển thị tìm kiếm của thư viện để thêm chức năng tìm kiếm. Tuy nhiên, IB thiết lập nó để thanh có thể nhìn thấy ở trên cùng của màn hình khi chế độ xem được hiển thị lần đầu tiên.

Tôi muốn biết cách ẩn thanh tìm kiếm theo mặc định nhưng vẫn có thể cuộn với chế độ xem bảng (xem ứng dụng Thư của Apple để làm ví dụ). Tôi đã thử gọi scrollRectToVisible:animated:vào viewDidLoadđể di chuyển xem bảng xuống, nhưng vô ích. Cách ưa thích để ẩn thanh tìm kiếm theo mặc định là gì?

Câu trả lời:


116

Trước tiên, hãy đảm bảo rằng, thêm UISearchBar vào tableHeaderView của UITableView để nó được cuộn với nội dung của bảng và không bị cố định ở đầu chế độ xem.

Thanh tìm kiếm không được tính là một hàng trong chế độ xem bảng, vì vậy nếu bạn cuộn đầu chế độ xem bảng xuống hàng đầu tiên, nó sẽ 'ẩn' thanh tìm kiếm:

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

hoặc trong Swift:

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

Đảm bảo không cuộn chế độ xem bảng trước khi nó chứa dữ liệu ( scrollToRowAtIndexPathsẽ tạo ra một ngoại lệ nếu đường dẫn chỉ mục đã cho không trỏ đến một hàng hợp lệ (tức là nếu chế độ xem bảng trống)).


12
Trên thực tế, tôi đang gặp sự cố trong đó chế độ xem bảng sẽ không cuộn nếu không có đủ hàng để lấp đầy màn hình - trong bảng có một hoặc hai hàng, mã này không thực hiện được gì. Đó có phải là hành vi được mong đợi không? Tôi có thể đi vòng quanh nó bằng cách nào đó không?
Tim

18
Tôi đã tìm ra cách: thay vì cuộn đến đường dẫn chỉ mục, hãy thay đổi độ lệch nội dung của chế độ xem cuộn của bảng thành CGRect ở mức 0,0, 44,0
Tim

107
Tim, đó là cách để đi! Tôi đã sử dụng self.tableView.contentOffset = CGPointMake (0, self.searchDisplayController.searchBar.frame.size.height);
Joe D'Andrea

1
Btw - khi tôi nhập mã này sau một lệnh gọi tới [tableView reloadData] khiến bảng của tôi chuyển từ 2 hàng đến đủ hàng để cho phép cuộn bình thường, tôi thấy rằng việc sử dụng phương thức contentOffset gây ra hiện tượng giật và ẩn tìm kiếm trong khi sử dụng phương thức scrollToRowAtIndexPath không có độ giật tương tự.
Chris R

1
Đây là cách cuối cùng duy nhất hoạt động trong mọi trường hợp. Cài đặt contentOffsetvới bất kỳ giá trị nào sẽ bị phá vỡ nếu bạn đang sử dụng bố cục bộ điều khiển chế độ xem phức tạp. Tôi không khuyên bạn nên nó.
eonil

45

Không thêm UISearchBar làm chế độ xem phụ của UITableView, điều này không cần thiết.

UITableView có thuộc tính tableHeaderView hoàn hảo cho việc này:

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

Nếu bạn không muốn xem nó theo mặc định:

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

Tôi cũng nhận được nút hủy để ẩn nó một lần nữa .... (và xóa bàn phím)

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

Đối với tôi, đây là giải pháp duy nhất tạo ra triển khai UISearchBar ẩn mà cảm giác như nó phù hợp với HIG. Các giải pháp khác mà nó bị "mắc kẹt" ở đầu bảng xem có cảm giác không tự nhiên.
kurtzmarc

1
Giải pháp này hoạt động tốt nhất. Đây nên là câu trả lời theo quan điểm của tôi.
darwindeeds

Giải pháp này là tốt (+1). Tuy nhiên, tableView không ẩn thanh tìm kiếm đúng cách trong một số trường hợp (trong trường hợp của tôi: khi bộ điều khiển chế độ xem bảng được đẩy trở lại từ bộ điều khiển chế độ xem khác). Có một câu hỏi về vấn đề này: stackoverflow.com/questions/15222186/… Mặc dù vậy, tôi nghĩ câu trả lời được cung cấp cho câu hỏi này không hoàn toàn tốt. @bandejapaisa, bạn có ý kiến ​​gì không?
Brian

3
Điều này hoạt động tốt đối với tôi, mặc dù thay vì mã hóa cứng 44 trong suốt, tôi khuyên bạn nên sử dụng self.tableView.tableHeaderView.frame.size.height trong viewWillAppear để cho phép các thay đổi mà Apple có thể thực hiện trong tương lai đối với chiều cao thanh tìm kiếm.
John Stephen

đưa nó vào viewWillAppearlà một ý tưởng tồi vì nó sẽ chạy mỗi khi bạn điều hướng trở lại chế độ xem của mình. Điều này có nghĩa là chế độ xem bảng của bạn sẽ từ từ giảm xuống. Con bọ khó chịu!
Sirens

25

Nội dungOffset đã được ghi nhận trong các bình luận của Tim và Joe D'Andrea, nhưng điều này được mở rộng một chút bằng cách thêm một hoạt ảnh để ẩn thanh tìm kiếm. Tôi nhận thấy có một chút bất ngờ khi thanh tìm kiếm biến mất.

Một bản cập nhật nhỏ cho những ai muốn nhắm mục tiêu iOS 4.0 trở lên, hãy thử cách này:

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

Câu trả lời trước:

[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
Tôi thấy rằng hoạt ảnh là chìa khóa cho giải pháp này. Cố gắng đặt độ lệch nội dung mà không có hoạt ảnh sẽ không có tác dụng gì. Tuy nhiên, thay vì sử dụng các phương thức hoạt ảnh (hoặc khối) trong mẫu này, tôi thấy rằng chỉ cần gọi [self.tableView setContentOffset: CGPointMake (0,44) animation: TRUE] là đủ hoạt động.
quickthyme

Nó dường như không hoạt động chút nào nếu không có hoạt ảnh. @quickthyme cũng nhận xét tương tự.
Thilo

5
Tôi đã thành công với điều này mà không cần các hoạt ảnh nếu bạn triển khai nó viewDidAppear:thay vì viewDidLoad.
wbyoung

8

Có nhiều câu trả lời cho giải pháp này, tuy nhiên không có câu trả lời nào hiệu quả với tôi.

Điều này hoạt động hoàn hảo. Không có hoạt ảnh và được thực hiện dựa trên-viewDidLoad

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

Ghi chú:

Mã giả sử bạn có mã searchBar @propertyđược liên kết với thanh tìm kiếm. Nếu không, bạn có thể sử dụng self.searchDisplayController.searchBarthay thế


đây là cái duy nhất làm việc cho tôi! , nhưng nó chỉ bỏ xemdidload ... vì vậy lần đầu tiên nó bị ẩn, nhưng sau đó không bị ẩn nữa khi ứng dụng de đang chạy. Và tôi đã thử đưa nó vào viewwillappear và viewdidappear nhưng hoạt động sai. Cảm ơn!
fguespe

@fguespe thật lạ .. ViewDidLoad sẽ được gọi mỗi khi chế độ xem được khởi tạo. Tôi chưa bao giờ thấy UISearchBar hiển thị sau khi quay lại từ một chế độ xem khác.
Matej

tôi đang sử dụng một ứng dụng theo thẻ. Có lẽ đó?
fguespe

@fguespe Tôi thấy đó có thể là vấn đề hmm. Rất tiếc, tôi không chắc bạn sẽ giải quyết vấn đề đó như -viewWillAppearthế nào nếu không hoạt động .. Nó có bị gọi khi bộ điều khiển tab chuyển sang chế độ xem không?
Matej

viewwillappear và viewdidappear được gọi, nhưng tôi đã thử với cả hai và chế độ xem giống như sai lệch. Nó không trả về kết quả mong đợi. Ý tôi là, một cái gì đó có, nhưng nó làm nó xấu.
fguespe

7

Đối với Swift 3+

Tôi đã làm điều này:

Khai báo điều này var:

    var searchController = UISearchController()

Và trong viewDidLoad()phương pháp

    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

Mục tiêu của tôi là ẩn thanh tìm kiếm được thêm vào tableHeaderView theo kiểu của TableView thuần túy trong bảng phân cảnh khi bộ điều khiển chế độ xem được tải và hiển thị thanh khi người dùng cuộn xuống ở đầu UITableView. Vì vậy, tôi đang sử dụng Swift và đã thêm tiện ích mở rộng:

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)
            }
        }
    }
}

trong viewDidLoad () chỉ cần gọi:

self.tableView.hideSearchBar()

5

Tất cả các giải pháp hiện tại không hoạt động đối với tôi trên iOS 8 khi không có đủ hàng để lấp đầy tableView vì iOS sẽ tự động điều chỉnh nội dung trong trường hợp này. (Mặc dù vậy, các câu trả lời hiện tại là tốt khi có đủ hàng)

Sau khi lãng phí 6 giờ cho vấn đề này, cuối cùng tôi đã có giải pháp này.

Tóm lại, bạn cần phải chèn các ô trống vào tableView nếu không có đủ ô, vì vậy kích thước nội dung của tableView đủ lớn để iOS sẽ không điều chỉnh inset cho bạn.

Đây là cách tôi đã làm điều đó trong Swift:

1.) khai báo một biến minimumCellNumdưới dạng thuộc tính lớp

var minimumCellNum: Int?

2.) tính toán minimumCellNumvà thiết lập tableView.contentOffsettrongviewWillAppear

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 trong tableView(tableView: UITableView, numberOfRowsInSection section: Int))

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

4.) Đăng ký một ô trống, có selectionthuộc tính None, trên bảng phân cảnh và trongtableView(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.) trong tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)

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

Đây không phải là một giải pháp hoàn hảo, nhưng đó là cách giải quyết duy nhất thực sự phù hợp với tôi trên iOS 8. Tôi muốn biết liệu có giải pháp nào gọn gàng hơn không.


Tôi đã phải làm điều này cho iOS 11. Riêng thiết lập contentOffset đã hoạt động đối với iOS 9/10 cho 0 ô trở lên và nó cũng hoạt động trên iOS 11 cho 8 ô trở lên. Bất cứ điều gì ít hơn yêu cầu giải pháp này. Có một lý do tại sao?
Tony

Tôi nghĩ rằng đoạn đầu tiên của bài đăng này giải thích tại sao.
Brian

Tôi đã hiểu đoạn đầu tiên, nhưng vẫn còn lạ là nó chỉ bị "hỏng" trên iOS 11 đối với tôi. Tôi đã mong đợi hành vi tương tự cho iOS 9, 10 và 11 khi số lượng ô giống nhau (ít hơn đủ). Cảm ơn một lần nữa và xin lỗi vì đã đưa lên một bài viết cũ!
Tony

4

Không có cách nào ở trên phù hợp với tôi, vì vậy đề phòng nếu ai đó sẽ gặp vấn đề tương tự.

Tôi đã searchBarđặt như tableHeaderViewtrên một bảng được nhóm trên iOS7. Trong viewDidLoadtôi phải tableView.contentOffset = CGPointMake(0, 44);giữ searchBar"ẩn" ban đầu. Khi người dùng cuộn xuống searchBarlà dsiplayed

Mục tiêu: ẩn tìm kiếmBar khi nhấn vào nút hủy

Trong searchBarCancelButtonClicked(searchBar: UISearchBar!)

Điều này không hoạt động: [yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; tableView đang cuộn lên quá nhiều, dẫn đến hàng 0 nằm sau toolBar.

Điều này không hoạt động: tableView.ContentOffset = CGPointMake(0, 44) - không có gì xảy ra

Điều này không hoạt động: tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height) - không có gì xảy ra

Điều này không hoạt động: tableView.setContentOffset(CGPointMake(0, 44), animated: true); Một lần nữa tableView lại cuộn lên quá nhiều, dẫn đến hàng 0 nằm sau toolBar.

Điều này đã hoạt động một phần: tableView.setContentOffset(CGPointMake(0, 0) nhưng titleForHeaderInSectionđã đi sau toolBar

CÔNG VIỆC NÀY: tableView.setContentOffset(CGPointMake(0, -20)

Có vẻ không logic nhưng chỉ -20 di chuyển nó lên đúng vị trí


Bạn thực sự không nên mã cứng điểm của bạn, tại sao bạn không sử dụng CGRectGetHeight(searchBar.bounds)?
Zorayr

Tôi đoán bạn phải làm điều đó trong viewDidLoad () / init (), nơi không có khung nào được thiết lập để bạn có được chiều cao của thanh tìm kiếm. Có thể bạn nên thử với viewDidLayoutSubviews ()
Kaushil Ruparelia

Nếu tableView chưa tải xong, không có ContentOffsetgiải pháp nào hoạt động
Maor

4

Nội dung bù đắp là cách để đi, nhưng nó không hoạt động 100% thời gian.

Nó không hoạt động nếu đang đặt estimatedRowHeightthành một số cố định. Tôi không biết công việc xung quanh được nêu ra. Tôi đã tạo một dự án hiển thị (các) vấn đề và tôi đã tạo một radar với Apple.

Kiểm tra dự án nếu bạn muốn có một ví dụ nhanh chóng về cách thiết lập tất cả.


1
Cảm ơn bạn! Đây là những gì tôi đang tìm kiếm. Bạn cần phải đi lên.
user2387149

3

Lưu ý rằng câu trả lời được chấp nhận sẽ bị lỗi nếu không có dữ liệu trong chế độ xem bảng. Và thêm nó vào viewDidLoad có thể không hoạt động trong một số trường hợp nhất định.

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

Do đó, thay vào đó hãy thêm dòng mã này:

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

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

2

Thành thật mà nói, không có câu trả lời nào thực sự giải quyết được vấn đề (đối với tôi). Nếu chế độ xem bảng của bạn không có hàng HOẶC chiều cao của hàng khác nhau, thì những câu trả lời này không đủ.

Điều duy nhất hoạt động:

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

Giải pháp tốt cho vấn đề bù đắp. Phù hợp với tôi khi sử dụng UINavigationController.
Andreas Kraft

1
Giải pháp không hoạt động khi số hàng không bao phủ toàn bộ màn hình - bạn có biết cách giải quyết nào cho điều này không?
Zorayr

Không chắc tôi hiểu điều này hoàn toàn. Điều này phù hợp với tôi khi tôi chỉ có một vài hàng trong bảng. Tuy nhiên tôi không sử dụng những điều sau đây: self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];.
p0lAris

2

Các scrollToRowAtIndexPathphương pháp gây ra một vụ tai nạn nếu có zero hàng trong bảng.

UITableView chỉ là một dạng xem cuộn, vì vậy bạn có thể chỉ cần thay đổi phần bù nội dung.

Điều này kiểm tra xem bạn có thứ gì đó làm tableHeaderView của mình không và giả sử bạn thực hiện thao tác cuộn để ẩn nó

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

1

Tôi thấy rằng ứng dụng "Ghi chú" không thể tìm kiếm các mục khi Chế độ xem bảng trống. Vì vậy, tôi nghĩ rằng nó chỉ sử dụng -(void)addSubview:(UIView *)viewđể thêm một bảng trống lúc đầu. Khi bạn thêm một mục vào mảng nguồn dữ liệu của nó, nó sẽ chạy một đoạn mã khác để tải tableView.

Vì vậy, giải pháp của tôi là:

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

Hi vọng điêu nay co ich :-)


1

Thay đổi giới hạn của tableView, điều này có thể được thực hiện bên trong viewDidLoadvà bạn không phải lo lắng về việc bảng có trống hay không (để tránh ngoại lệ).

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

Sau khi người dùng cuộn xuống bảng, thanh tìm kiếm sẽ xuất hiện và hoạt động bình thường


1

Các câu trả lời khác cho câu hỏi này hoàn toàn không hoạt động đối với tôi, có hành vi kỳ lạ khi tableView có 0 hàng hoặc làm lộn xộn vị trí cuộn khi qua lại giữa các mục hàng gốc và mục hàng lồng nhau. Điều này đã làm việc cho tôi (mục đích là để ẩn UISearchBar khi tải):

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) 
    }
}

Giải thích
Bất cứ khi nào ý tableViewmuốn xuất hiện, mã này sẽ kiểm tra xem thanh UISearchBar có hiển thị không (có nghĩa là yvị trí của contentOffset, hay còn gọi là vị trí cuộn, là 0). Nếu có, nó chỉ cần cuộn xuống chiều cao của thanh tìm kiếm. Nếu searchBar không hiển thị (nghĩ rằng danh sách các mục lớn hơn tableView), thì nó sẽ không thử và cuộn vào tableView, vì điều này sẽ làm rối loạn vị trí khi bạn quay lại từ một mục hàng lồng nhau.

Lưu ý bên lề
Tôi khuyên bạn nên đặt mã này theo một phương pháp riêng để đảm bảo trách nhiệm duy nhất và cung cấp cho bạn khả năng tái sử dụng để gọi nó bất cứ lúc nào trong mã của bạn.


1

Nếu bảng của bạn luôn có ít nhất một hàng, chỉ cần cuộn đến hàng đầu tiên của bảng và thanh tìm kiếm sẽ tự động bị ẩn.

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

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

Nếu bạn đặt đoạn mã trên vào viewDidLoad , nó sẽ báo lỗi vì tableView chưa được tải, vì vậy bạn phải đặt nó vào viewDidAppear vì đến thời điểm này tableView đã được tải.

Nếu bạn đặt nó trên viewDidAppear , mỗi khi bạn mở tableView, nó sẽ cuộn lên trên cùng.

Có thể bạn không muốn hành vi này nếu tableView vẫn mở, như khi nó là một UITabBar View Controller hoặc khi bạn thực hiện một segue và sau đó quay lại. Nếu bạn chỉ muốn nó cuộn lên đầu khi tải ban đầu, bạn có thể tạo một biến để kiểm tra xem nó có phải là tải ban đầu hay không để nó cuộn lên đầu chỉ một lần.

Trước tiên, hãy xác định một biến được gọi là isInitialLoad trong lớp bộ điều khiển chế độ xem và đặt nó bằng "true":

var isInitialLoad = true

Sau đó, kiểm tra xem isInitialLoad có đúng trên viewDidAppear không và nếu đúng, hãy cuộn lên trên cùng và đặt biến isInitialLoad thành false:

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

            isInitialLoad = false
        }

1

Mã dưới đây đang hoạt động cho tôi

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

1

Tôi đã thử đặt bù đắp nội dung và scrollToIndexpath nhưng không có gì hoạt động tốt. Tôi đã xóa cài đặt tableHeaderView dưới dạng searchBar khỏi viewDidLoad và đặt nó trong ủy quyền scrollview như bên dưới

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)
    }
}

Điều này hoạt động giống như một sự quyến rũ. Cài đặt bù đắp nội dung nhằm mục đích cuộn mượt


0

Đừng quên xem xét thanh trạng tháithanh điều hướng . Bộ điều khiển chế độ xem bảng của tôi được nhúng trong bộ điều khiển điều hướng, trong viewDidAppear:

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

đã làm cho tôi.


0

Đối với Swift:

Chỉ cần tạo độ lệch y cho nội dung chế độ xem bảng, giống như chiều cao của thanh tìm kiếm.

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

0

Swift 3

hoạt động với bảng trống quá!

Trong môi trường của tôi, tôi tải các ô tùy chỉnh bằng tệp xib và rowHeight được đặt tự động.

    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

Tôi đã có vấn đề tương tự. Và cách duy nhất tôi tìm thấy để giải quyết vấn đề này là sử dụng trình quan sát giá trị khóa trên thuộc tính UITableView contentOffset.

Sau một số gỡ lỗi, tôi nhận ra rằng vấn đề xuất hiện chỉ khi kích thước nội dung chế độ xem bảng nhỏ hơn chế độ xem bảng. Tôi bắt đầu KVO khi ở trên viewWillAppear. Và điều khiển dừng KVO 0,3 giây sau khi chế độ xem xuất hiện. Mỗi khi contentOffset trở thành 0.0, KVO phản ứng và đặt contentOffset trên chiều cao của thanh tìm kiếm. Tôi dừng KVO không đồng bộ sau 0,3 giây vì bố cục chế độ xem sẽ đặt lại contentOffset ngay cả khi chế độ xem xuất hiện.

- (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"];
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.