2014-12-03 24 views
7

Tôi đang làm việc trên một ứng dụng mà tôi phải đối mặt với một vấn đề xa lạ. Tôi đã tạo ra một UITableViewController trong bảng phân cảnh và thêm một ô mẫu thử nghiệm. Trong ô này, tôi đã thêm phần tử UILabel và UILabel này chiếm toàn bộ ô. Tôi đã thiết lập nó với Auto Layout và thêm các ràng buộc trái, phải, trên và dưới. UILabel chứa một số văn bản.iOS 8 UITableView hàng đầu tiên có sai chiều cao

Bây giờ trong mã của tôi, tôi khởi tạo các rowHeight và estimatedRowHeight của xem bảng:

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.tableView.rowHeight = UITableViewAutomaticDimension 
    self.tableView.estimatedRowHeight = 50 
} 

Và tôi tạo ra các tế bào như sau:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    var cell : UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("HelpCell") as? UITableViewCell 
    if(cell == nil) { 
     cell = UITableViewCell(style: .Default, reuseIdentifier: "HelpCell") 
    } 
    return cell! 
} 

tôi trở lại hai hàng trong bảng của tôi lượt xem. Ở đây có vấn đề của tôi: chiều cao của hàng đầu tiên là cách lớn. Có vẻ như hàng thứ hai, thứ ba, vv đều có chiều cao chính xác. Tôi thực sự không hiểu tại sao lại như vậy. Ai đó có thể giúp tôi với điều này?

Trả lời

15

Tôi đã có một vấn đề mà chiều cao tế bào không chính xác trên tải đầu tiên, nhưng sau khi di chuyển lên chiều cao của các tế bào đã được cố định.

Tôi đã thử tất cả các 'bản sửa lỗi' khác nhau cho vấn đề này và sau đó cuối cùng thấy rằng việc gọi các chức năng này sau khi ban đầu gọi self.tableView.reloadData.

  self.tableView.reloadData() 
      // Bug in 8.0+ where need to call the following three methods in order to get the tableView to correctly size the tableViewCells on the initial load. 
      self.tableView.setNeedsLayout() 
      self.tableView.layoutIfNeeded() 
      self.tableView.reloadData() 

Chỉ thực hiện các cuộc gọi bố cục bổ sung sau lần tải đầu tiên.

tôi thấy thông tin rất hữu ích này ở đây: https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8/issues/10

Cập nhật: Đôi khi bạn có thể phải cũng hoàn toàn cấu hình di động của bạn trong heightForRowAtIndexPath và sau đó trở về chiều cao di động tính toán. Kiểm tra liên kết này cho một ví dụ tốt về điều đó, http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout, đặc biệt là phần trên heightForRowAtIndexPath.

Cập nhật 2: Tôi cũng đã tìm thấy nó RẤT lợi để ghi đè estimatedHeightForRowAtIndexPath và cung cấp phần nào chính xác chiều cao hàng ước tính. Điều này rất hữu ích nếu bạn có UITableView với các ô có thể là tất cả các loại có độ cao khác nhau.

Dưới đây là một việc thực hiện mẫu giả tạo của estimatedHeightForRowAtIndexPath:

public override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 

    let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyCell 

    switch cell.type { 
    case .Small: 
     return kSmallHeight 
    case .Medium: 
     return kMediumHeight 
    case .Large: 
     return kLargeHeight 
    default: 
     break 
    } 
    return UITableViewAutomaticDimension 
} 

Cập nhật 3: (! Woo-hoo)UITableViewAutomaticDimension đã được cố định dành cho iOS 9. Vì vậy, bạn là các ô nên tự động định kích thước mà không phải tính chiều cao ô theo cách thủ công.

0

Trong iOS 8, giao estimatedRowHeight một giá trị biến trên iOS mới 8 tính năng tự động tính toán chiều cao hàng. Điều này có nghĩa là chiều cao của ô được bắt nguồn bằng cách sử dụng các ràng buộc bên trong của nó từ trong ra ngoài. Nếu có điều gì đó sai trái với những ràng buộc đó, bạn sẽ nhận được kết quả kỳ quặc. Vì vậy, có điều gì đó sai trái với những hạn chế về tế bào của bạn. Chúng có thể mơ hồ; đó là lý do thông thường cho sự mâu thuẫn. Tuy nhiên đó là tất cả những gì tôi có thể nói với bạn, vì bạn đã không thực sự hiển thị/mô tả các ràng buộc.

+0

Tôi khá chắc chắn rằng những hạn chế của tôi không phải là mơ hồ kể từ khi tôi chỉ có 4 chế trên UILabel. Bạn có bất cứ đề nghị nào khác có thể là sai? – Devos50

+1

Đừng "khá chắc chắn". Có nhiều cách để tìm hiểu xem bạn có bố cục không rõ ràng hay không. Sử dụng chúng. Đừng sử dụng cảm giác ruột của bạn; đó là vấn đề, không phải là giải pháp. Nếu bạn _knew_ những gì tạo thành bố cục rõ ràng, chúng tôi sẽ không ở đây với bạn gặp rắc rối, phải không? Lắng nghe những gì tôi nói với bạn. Thực tế đơn giản là 4 ràng buộc ghim trái, phải, trên và dưới là _không đủ_. Các ràng buộc của bạn có thể là _are_ mơ hồ. – matt

0

Tôi đề nghị loại bỏ các hạn chế dưới trên UILabel. Nó sẽ thay đổi kích thước theo văn bản và các tế bào nên thay đổi kích cỡ là tốt.

Nếu điều đó đã không giải quyết được vấn đề này, hãy thử thêm những điều sau đây trong viewDidLoad():

self.tableView.reloadData()

+0

Cảm ơn bạn đã đề xuất nhưng nếu tôi xóa ràng buộc, UILabel sẽ không tự thay đổi kích thước. Ngoài ra, tải lại dữ liệu không giải quyết được sự cố. – Devos50

+0

Bạn có thể chia sẻ ảnh chụp màn hình các ràng buộc của mình với ô không? – Armin

2

Khi Apple nói trong mô tả của setNeedsLayout:

Phương pháp này không có hiệu lực ngay lập tức một cập nhật, nhưng thay vì chờ chu kỳ cập nhật tiếp theo, bạn có thể sử dụng nó để vô hiệu hóa bố cục của nhiều chế độ xem trước khi bất kỳ lượt xem nào được cập nhật. Hành vi này cho phép bạn hợp nhất tất cả các cập nhật bố cục của mình thành một chu kỳ cập nhật, thường tốt hơn cho hiệu suất.

Vì lý do này, bạn nên thêm các dòng mã cần thiết (cần được thực hiện với bố cục đúng) trong dispatch_after block (sẽ đưa phương thức của bạn vào hàng đợi RunLoop). Và mã của bạn sẽ được thực hiện sau khi bố cục nhu cầu áp dụng.

Ví dụ:

- (void)someMethod { 

[self.tableView reloadData]; 

[self.tableView setNeedsLayout]; 

[self.tableView layoutIfNeeded]; 

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 

      //code which should be executed with the right size of table 

     }); 
Các vấn đề liên quan