Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
UITableView';s contentInset.top比iOS10中的值大20点_Ios_Swift_Ios10 - Fatal编程技术网

UITableView';s contentInset.top比iOS10中的值大20点

UITableView';s contentInset.top比iOS10中的值大20点,ios,swift,ios10,Ios,Swift,Ios10,我有一个SearchViewController,作为ViewController的一部分,我有一个UISearchController(带有一个名为SearchResultsTableViewController的SearchResultsTableViewController)。我注意到我的SearchResultsTableViewController的UITableViewcontentInset.top比它应该的多20个点,尽管它在iOS8/9上很好,并且具有automatically

我有一个
SearchViewController
,作为
ViewController
的一部分,我有一个
UISearchController
(带有一个名为
SearchResultsTableViewController
SearchResultsTableViewController
)。我注意到我的
SearchResultsTableViewController
UITableView
contentInset.top
比它应该的多20个点,尽管它在iOS8/9上很好,并且具有
automaticallyAdjustScrollViewInsets
=true。如果我从这个
ViewController
执行到另一个,然后返回,我看到
contentInset.top
又增加了20个点。同样,这在iOS8/9上不会发生。下面是显示这种行为的示例

以下是两个相关的
视图控制器的代码

class SearchViewController: UIViewController, UISearchBarDelegate, UISearchControllerDelegate {

    @IBOutlet var tableView: UITableView!
    @IBOutlet var backgroundImageView: UIImageView!
    var searchController: UISearchController!
    var backBarButtonItem: UIBarButtonItem!
    var searchButtonTapped = false
    @IBOutlet var titleLabel: SpringLabel!
    @IBOutlet var loadingIndicatorView: UIActivityIndicatorView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let searchResultsVC = self.storyboard!.instantiateViewController(withIdentifier: "SearchResultsTableViewController") as! SearchResultsTableViewController
        searchResultsVC.searchController = self

        searchController = UISearchController(searchResultsController: searchResultsVC)
        searchController.searchResultsUpdater = searchResultsVC
        searchController.hidesNavigationBarDuringPresentation = false

        searchController.dimsBackgroundDuringPresentation = true
        searchController.delegate = self
        searchController.searchBar.delegate = self
        searchController.searchBar.placeholder = "Search Courses"
        searchController.view.backgroundColor = UIColor.clear
        searchController.searchBar.keyboardAppearance = .dark

        self.setSearchBarCaretColor(UIColor(red: 0.24, green: 0.34, blue: 0.19, alpha: 1.0))
        self.setSearchBarFontSize(17.0)
        self.navigationItem.titleView = searchController.searchBar

        self.definesPresentationContext = true
        self.backBarButtonItem = self.navigationItem.leftBarButtonItem
        self.backgroundImageView.clipsToBounds = true

        self.titleLabel.alpha = 0
        self.titleLabel.layer.shadowColor = UIColor.black.cgColor
        self.titleLabel.layer.shadowOpacity = 0.8
        self.titleLabel.layer.shadowOffset = CGSize(width: 2.0, height: 2.0)
        self.titleLabel.layer.shouldRasterize = true
        self.titleLabel.layer.rasterizationScale = UIScreen.main.scale

        self.loadingIndicatorView.layer.zPosition = CGFloat.greatestFiniteMagnitude
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.perform(#selector(SearchViewController.showKeyboard), with: nil, afterDelay: 0.01)
        searchBarTextDidBeginEditing(searchController.searchBar)
    }

    func showKeyboard() {
        self.searchController.searchBar.becomeFirstResponder()
    }

    func hideKeyboard() {
        self.searchController.searchBar.resignFirstResponder()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.titleLabel.delay = 0.1
        self.titleLabel.animation = "zoomIn"
        self.titleLabel.duration = 0.6
        self.titleLabel.animate()

        let selectedRowIndexPath = self.tableView.indexPathForSelectedRow
        if ((selectedRowIndexPath) != nil) {
            self.tableView.deselectRow(at: selectedRowIndexPath!, animated: true)
            self.transitionCoordinator?.notifyWhenInteractionEnds({ context in
                if (context.isCancelled) {
                    self.tableView.selectRow(at: selectedRowIndexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
                }
            })
        }
    }

    func setSearchBarCaretColor(_ color : UIColor) {
        let view = searchController.searchBar.subviews[0]
        let subViewsArray = view.subviews
        for subView in subViewsArray {
            if subView.isKind(of: UITextField.self) {
                subView.tintColor = color
            }
        }
    }

    func setSearchBarFontSize(_ pointSize : CGFloat) {
        let view = searchController.searchBar.subviews[0]
        let subViewsArray = view.subviews
        for subView in subViewsArray {
            if subView.isKind(of: UITextField.self) {
                let textField = subView as! UITextField
                textField.font = UIFont.systemFont(ofSize: pointSize)
            }
        }
    }

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
//This doesn't animate for some reason, so don't use it.
            if (UI_USER_INTERFACE_IDIOM() != .pad) { //Because the iPad (for some reason) doesn't ever show the Cancel button, so keep the back button.
                UIView.animate(withDuration: 0.3, animations: { self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: UIView()) }, completion: { Void in
                self.navigationItem.setHidesBackButton(true, animated: false)
            })
        }
    }


    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
        if (self.searchButtonTapped == false) {
            self.navigationItem.leftBarButtonItem = self.backBarButtonItem
            self.navigationItem.setHidesBackButton(false, animated: true)
        } else {
            self.searchButtonTapped = false
        }
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        self.navigationItem.leftBarButtonItem = self.backBarButtonItem
        self.navigationItem.setHidesBackButton(false, animated: true)
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        self.searchButtonTapped = true
        searchBar.resignFirstResponder()
    }

}
下面是SearchResultsTableViewController:

class SearchResultsTableViewController: UITableViewController, UISearchResultsUpdating {

    var resultsArray = [CourseResult]()
    var emptySearchResultsView : EmptySearchResultsView!

    var keyboardActive = false
    var keyboardHeight : CGFloat = 0.0

    var searchController : SearchViewController!
    var query = PFQuery(className: "Course")

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.backgroundColor = UIColor.clear
        self.tableView.estimatedRowHeight = 140
        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.keyboardDismissMode = .onDrag

        self.emptySearchResultsView = EmptySearchResultsView.construct(self) as EmptySearchResultsView
        emptySearchResultsView.translatesAutoresizingMaskIntoConstraints = true
        self.emptySearchResultsView.isHidden = true
        self.tableView.addSubview(emptySearchResultsView)

        query.whereKey("institution", equalTo: "College")
        query.limit = 20
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        self.registerKeyboardNotifications()
        let selectedRowIndexPath = self.tableView.indexPathForSelectedRow
        if ((selectedRowIndexPath) != nil) {
            self.tableView.deselectRow(at: selectedRowIndexPath!, animated: true)
            self.transitionCoordinator?.notifyWhenInteractionEnds({ context in
                if (context.isCancelled) {
                    self.tableView.selectRow(at: selectedRowIndexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
                }
            })
        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        self.unregisterKeyboardNotifications()
    }

    var lastSearch = ""
    func updateSearchResults(for searchController: UISearchController) {
        guard searchController.isActive else { return }
        if (lastSearch == searchController.searchBar.text!) {
            return
        }
        self.lastSearch = searchController.searchBar.text!
        query.cancel()
        self.emptySearchResultsView.isHidden = true

        if (searchController.searchBar.text?.characters.count == 0) {
            resultsArray.removeAll()
            self.tableView.reloadData()
        }

        if ((searchController.searchBar.text?.characters.count)! > 0) {
            self.searchController.loadingIndicatorView.startAnimating()
            var searchString = searchController.searchBar.text!
            searchString = searchString.lowercased()
            var searchStringArray = searchString.components(separatedBy: " ")
            searchStringArray = searchStringArray.filter { $0 != "" }
            //print(searchStringArray.description)
            query.whereKey("searchTerms", containsAllObjectsIn: searchStringArray)
            query.findObjectsInBackground(block: { (results, error) -> Void in
                if (error == nil) {
                    self.resultsArray = []
                    let courseResultsArray = results! as [PFObject]
                    for result in courseResultsArray {
                        //removed all of this jargon.
                    }
                    self.searchController.loadingIndicatorView.stopAnimating()
                    self.tableView.reloadData()
                    if (self.resultsArray.count == 0) {
                        self.emptySearchResultsView.isHidden = false
                    } else {
                        self.emptySearchResultsView.isHidden = true
                    }
                } else {
                    print(error?.localizedDescription)
                    self.searchController.loadingIndicatorView.stopAnimating()
                }
            })
        }
    }

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        if (self.keyboardActive == true) {
            self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - self.keyboardHeight - self.tableView.contentInset.top)
            self.emptySearchResultsView.setNeedsLayout()
        } else {
            self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - self.tableView.contentInset.top)
            self.emptySearchResultsView.setNeedsLayout()
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return resultsArray.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellContent: CourseResult = self.resultsArray[(indexPath as NSIndexPath).row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "CourseResultTableViewCell", for: indexPath) as! CourseResultTableViewCell
        cell.backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
        cell.backgroundColor = UIColor.clear
        cell.courseLabel.text = cellContent.courseCode + " - " + cellContent.courseName
        cell.universityLabel.text = cellContent.university
        cell.facultyLabel.text = cellContent.faculty

        cell.leftHandSideImageView.image = UIImage(named: cellContent.faculty)
        cell.leftHandSideImageView.layer.shadowColor = UIColor.black.cgColor
        cell.leftHandSideImageView.layer.shadowOpacity = 0.6
        cell.leftHandSideImageView.layer.shouldRasterize = true
        cell.leftHandSideImageView.layer.rasterizationScale = UIScreen.main.scale

        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let schedulesVC = self.storyboard!.instantiateViewController(withIdentifier: "SchedulesViewController") as! SchedulesViewController
        schedulesVC.selectedCourse = self.resultsArray[(indexPath as NSIndexPath).row]
        self.searchController.show(schedulesVC, sender: tableView)
    }

    func registerKeyboardNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(SearchResultsTableViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(SearchResultsTableViewController.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func unregisterKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func keyboardWillShow(_ notification: Notification) {
        if (UI_USER_INTERFACE_IDIOM() != .phone) { //Because devices like iPads don't have they keyboards affect the error screen visibility much.
            return
        }
        if let keyboardFrame = ((notification as NSNotification).userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue {
            UIView.animate(withDuration: 0.6, animations: { self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - keyboardFrame.height - self.tableView.contentInset.top)
                self.emptySearchResultsView.layoutIfNeeded()
            })
            self.keyboardActive = true
            self.keyboardHeight = keyboardFrame.height
        }
    }

    func keyboardWillHide(_ notification: Notification) {
        if (UI_USER_INTERFACE_IDIOM() != .phone) {
            return
        }
        UIView.animate(withDuration: 0.6, animations: { self.emptySearchResultsView.frame = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.bounds.height - self.tableView.contentInset.top)
            self.emptySearchResultsView.layoutIfNeeded()
        })
        self.keyboardActive = false
    }

}
每个
viewcontroller
在情节提要中都有自己的表示形式

有人知道我为什么会看到这种行为吗?这种行为只有在iOS10中才能看到?这个问题发生在我测试过的各种设备上

注意:只需忽略与结果相关的任何字符串解析代码或任何其他相关代码。我删除了一些内容,试图使代码更加连贯,还有json解析代码,等等


唯一对我有效的解决方案(这并不理想)是检查设备是否运行iOS10,并根据状态栏和导航栏的高度动态调整
contentInset.top
。显然,我必须关闭
自动调整滚动视图插图来执行此操作。

我也遇到了这个问题。你找到解决这个问题的方法了吗?我还注意到,每次搜索结果控制器出现时,它都会调用
updateSearchResults
。这使得每次tableView顶部的空间都很大,并且整个tableView都会重新加载。这在iOS<10时没有发生。苹果的情况是,这应该只出现在iOS的测试版中:|我唯一能解决这一问题的方法是根据运行ios10或更高版本的设备的状态栏高度、导航栏高度等手动设置uitableview的contentInset。这个解决方案非常有效,但不应该这样做。