簡體   English   中英

從 iOS 11 搜索控制器導航時不需要的 UITableView 重新加載動畫

[英]Unwanted UITableView reload animation when navigating from iOS 11 search controller

我有一個帶有包含聊天列表的表視圖的視圖控制器,一個嵌入在導航項中的搜索控制器(iOS 11 功能)

let searchController = UISearchController(searchResultsController: nil)
searchController.dimsBackgroundDuringPresentation = false
navigationItem.searchController = searchController
definesPresentationContext = true

當用戶點擊表視圖中的聊天時,應用程序會推送一個新的視圖控制器和另一個包含該聊天消息的表視圖。 這就像它應該的那樣工作:

在此處輸入圖像描述

問題是,當用戶激活搜索控制器,找到一些聊天並點擊它時,包含帶有聊天消息的表視圖的推送視圖控制器會對不應該發生的表視圖執行一些非常奇怪的動畫

在此處輸入圖像描述

我在實際導航之前加載數據,並在viewDidLoad中僅使用表視圖上的reload()將其綁定到表視圖。 有問題的表視圖使用自動布局和自定義單元格。

這個問題非常類似於調用 reloadData 時 UITableView 有不需要的動畫,但對我來說它只發生在 iOS 11 搜索控制器處於活動狀態時。

編輯:如果我刪除tableView.rowHeight = UITableViewAutomaticDimension並使用固定高度func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat問題仍然存在

如果您只是在推送新的 viewController 之前隱藏 searchBar,那么它可能會解決您的問題。

您需要為 searchBarCancelButton 創建一個全局變量,並在搜索內容時從其子視圖中找到取消按鈕

let buttons = searchController.searchBar.subviews.first?.subviews.filter { (view) -> Bool in
            return NSStringFromClass(view.classForCoder) == "UINavigationButton"
        } as? [UIButton]
        searchBarCancelButton = buttons?.first

然后你可以手動取消它。

self.searchBarCancelButton?.sendActions(for: .touchUpInside)

您可以嘗試在出列並設置單元格內容后立即調用cell.layoutIfNeeded()

iOS 11 徹底改進了安全區域 API,包括滾動視圖插入調整行為,忽略時可能會導致不需要的動畫。 因此,禁用帶有不需要動畫的滾動視圖的自動內容插入調整:

if #available(iOS 11.0, *) {
    tableView.contentInsetAdjustmentBehavior = .never
} else {
    // < iOS 11 logic
}

就個人而言,我會在展示新的視圖控制器之前簡單地隱藏 searchView 控制器。 (例如,將 UIView.animates 與完成處理程序一起使用)

我不會嘗試進一步調查,因為自 iOS11 以來,安全區域管理中存在一個深奧的問題。 錯誤? :)

甚至啟動屏幕布局也沒有得到正確處理。 很多專業標志在發布時都錯過了中間部分!

不要在viewDidLoadviewWillAppear中調用reloadData()方法。 而不是在viewDidLoad中使用空數據重新加載您的 tableView,這樣您的tableView將不顯示任何內容,然后在您的viewDidAppear中調用reloadData()方法來加載您的所有聊天記錄。 這將限制您的 tableView 加載不需要的動畫。

var shouldShowEmpty = true

func viewDidLoad() {
    super.viewDidLoad()
    tableView.reloadData()
}
func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    shouldShowEmpty = false
    tableView.reloadData()
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if shouldShowEmpty {
            return 0
        }
        return yourArray.count
    }

根據附件,看起來由於自動布局,單元格元素的高度為零( UILabel or UIImageView )然后當表格視圖重新加載時它突然獲取單元格內的數據,從而增加其高度(自動尺寸或其他)導致此動畫.

嘗試在沒有動畫的情況下推送它或嘗試設置修復單元格元素的高度和寬度並檢查它是否仍在顯示此動畫。

您是否在不調用 UISearchBar 的情況下進行檢查,如果您在任何單元格上選擇相同的動畫正在發生? 或者您是否嘗試刪除 UISearchbar 並選擇單元格並檢查動畫部分?

請分享您的代碼,以便我們看得更清楚。

我遇到過類似的問題,我相信解決方案是一樣的。 鍵盤導致了問題,更正確的是,keyboardWillHideNotification 觸發器。 您在底部有文本字段,它可能會監聽鍵盤顯示/隱藏的通知,如果您為底部約束設置動畫,則觸發 layoutIfNeeded() 以便您的鍵盤不會與您的文本字段重疊。 因此,當您在搜索文本字段中完成搜索時,會在不需要的時間觸發 keyboardWillHideNotification。 我通過調用解決了我的問題:

resignFirstResponder()

對於導致此事件的文本字段。 在我的例子中,那是在你按下按鈕之后,我相信它在搜索表視圖中的 didSelect tableView 單元格中。

如果您在這個問題上仍然很活躍,請告訴我您是否設法解決了它。 我為了解決這個問題而傷透了腦筋,這顯然是如此簡單明了。

  • 在 VC2 中,在重新加載表之前嘗試延遲功能

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { tableView.reloadData }

要不然

  • 在 VC1 中, didSelect在推送到 VC2 之前退出搜索控制器的第一響應者

要么

  • 在 VC1 中, didSelect退出搜索控制器的第一響應者,並在推送到 VC2 之前設置延遲

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM