Adding observer for KVO without pointers using Swift

后端 未结 5 913
灰色年华
灰色年华 2020-12-05 00:28

In Objective-C, I would normally use something like this:

static NSString *kViewTransformChanged = @\"view transform changed\";
// or
static const void *kVie         


        
5条回答
  •  余生分开走
    2020-12-05 01:17

    Swift 4 - observing contentSize change on UITableViewController popover to fix incorrect size

    I had been searching for an answer to change to a block based KVO because I was getting a swiftlint warning and it took me piecing quite a few different answers together to get to the right solution. Swiftlint warning:

    Block Based KVO Violation: Prefer the new block based KVO API with keypaths when using Swift 3.2 or later. (block_based_kvo).

    My use case was to present a popover controller attached to a button in a Nav bar in a view controller and then resize the popover once it's showing - otherwise it would be too big and not fitting the contents of the popover. The popover itself was a UITableViewController that contained static cells, and it was displayed via a Storyboard segue with style popover.

    To setup the block based observer, you need the following code inside your popover UITableViewController:

    // class level variable to store the statusObserver
    private var statusObserver: NSKeyValueObservation?
    
    // Create the observer inside viewWillAppear
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        statusObserver = tableView.observe(\UITableView.contentSize,
            changeHandler: { [ weak self ] (theTableView, _) in self?.popoverPresentationController?.presentedViewController.preferredContentSize = theTableView.contentSize
            })
    }
    
    // Don't forget to remove the observer when the popover is dismissed.
    override func viewDidDisappear(_ animated: Bool) {
        if let observer = statusObserver {
            observer.invalidate()
            statusObserver = nil
        }
    
        super.viewDidDisappear(animated)
    }
    

    I didn't need the previous value when the observer was triggered, so left out the options: [.new, .old] when creating the observer.

提交回复
热议问题