ios - 使用 viewDidLayoutSubviews 检测 UITableView 滚动会导致过多的回调

标签 ios swift uitableview if-statement parallax

我有一个 tableView,它是我在 Github 上找到的 Parallax table view 的子类。完成所有表格 View 的正常设置(删除了一些因为它不相关)。

class EventDetailTableViewController: ParallaxTableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the image:
        self.imageView.image = eventImage

        self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
        self.navigationController?.navigationBar.shadowImage = UIImage()
        self.navigationController?.navigationBar.translucent = true
    }


    // MARK: - UITableViewDelegate
     override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    override    
     func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 4
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
       // SET UP CELL
    }

    @IBAction func backButtonPressed(sender: AnyObject) {
        print("backButtonPressed")
        self.navigationController?.navigationBar.translucent = false

        self.navigationController?.navigationBar.barTintColor = UIColor(red: 227/255, green: 38/255, blue: 54/255, alpha: 1.0)

        self.navigationController?.popViewControllerAnimated(true)
    }
} // END OF VIEWCONTROLLER CLASS

这里需要注意的重要事项是我已使 navigationBar 透明。当 backButtonPressed 被调用时,我希望将 navigationBar.Color 改回之前 View Controller 的颜色(红色)。所以我在 backButtonPressed()

中编写了代码

这是我的视差代码。请查看最后一个函数 moveImage()。我有一个简单的效果,当 tableview 向下滚动到足以描述 navigationBar 出现时标题为“Event Description”

class ParallaxTableViewController: UITableViewController {

    // Create the UIView
    //var bottomFloatingView =  UIView()

    // Create the UIImageView
    let imageView = UIImageView()

    // Set the factor for the parallaxEffect. This is overwritable.
    var parallaxFactor:CGFloat = 2

    // Set the default height for the image on the top.
    var imageHeight:CGFloat = 320 {
        didSet {
            moveImage()
        }
    }

    // Initialize the scrollOffset varaible.
    var scrollOffset:CGFloat = 0 {
        didSet {
            moveImage()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Set the contentInset to make room for the image.
        self.tableView.contentInset = UIEdgeInsets(top: imageHeight, left: 0, bottom: 0, right: 0)

        // Change the contentMode for the ImageView.
        imageView.contentMode = UIViewContentMode.ScaleAspectFill

        // Add the imageView to the TableView and send it to the back.
        view.addSubview(imageView)
        view.sendSubviewToBack(imageView)
    }

    override func viewDidLayoutSubviews() {
        // Update the image position after layout changes.
        moveImage()
    }

    // Define method for image location changes.
    func moveImage() {
        let imageOffset = (scrollOffset >= 0) ? scrollOffset / parallaxFactor : 0
        let imageHeight = (scrollOffset >= 0) ? self.imageHeight : self.imageHeight - scrollOffset
        imageView.frame = CGRect(x: 0, y: -imageHeight + imageOffset, width: view.bounds.width, height: imageHeight)

        if imageOffset > 150 {
            print("imageOffSet")
            self.navigationItem.title = "Event Description"
            self.navigationController?.navigationBar.translucent = false
            self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()
            self.navigationController?.navigationBar.shadowImage = nil

        } else {
            print("else")
            self.navigationItem.title = ""
            self.navigationController?.navigationBar.shadowImage = UIImage()
            self.navigationController?.navigationBar.translucent = true

            // This is being called after the back button is being pressed. Which means this else function overrides my backButtonPressed() therefore making my navigation bar in the new VC not the correct color.
        }
    }
}

正如您在我的笔记中看到的,在调用 backButtonPressed() 之后,将再次调用此 else 函数。因此,它不会在新 VC 中给我所需的红色,而是让它保持半透明。如何在调用 backButtonPressed 时停止调用此 else 函数?

最佳答案

viewDidLayoutSubviews 永远不应参与响应用户事件。它是一种很少使用的内部生命周期方法,除非您将程序化 NSLayoutConstraints 添加或修改到已经添加到 Storyboard 中的方法。它被调用得非常频繁且明显冗余。

改为使用表委托(delegate)方法。特别是 UITableViewDelegate 继承自 UIScrollViewDelegate 所以引用:

UITableView Scroll event

然后查询 tableView 本身的可见性信息,例如indexPathsForVisibleRows:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/occ/instp/UITableView/indexPathsForVisibleRows

关于ios - 使用 viewDidLayoutSubviews 检测 UITableView 滚动会导致过多的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39088037/

相关文章:

ios - static UITableViewCell 如何防止 Contenttview 选择

iphone - 重新排序控件未显示在 TableView 中

ios - 通过单击 TableView 中的单元格打开新的 View Controller - Swift iOS

ios - 动态生成 Eureka 表单行

ios - viewDidLoad 上的 View 导出为零

swift - 在 Swift 中使用 deinit 和 defer 进行资源释放的区别

swift - 自定义分段控制效果

ios - 嵌入在 UITableViewCell 中的动态、自定义布局 UICollectionView

ios - 原因: image not found when running UI tests using a development pod

iOS - 将 IFNULL(...) JSON 键转换为对象属性