Dynamic height using Auto Layout in Today Extensio

2019-07-27 07:21发布

问题:

EDIT: My "original" problem has been solved, it was restricted to 110 height, by "<NSAutoresizingMaskLayoutConstraint:0x6000000985b0 h=--& v=--& UIView:0x7fc83af0aeb0.height == 110 (active)>", but that was before I read about NCWidgetDisplayMode, .Compact and .Expanded, which apparently was introduced in iOS 10.

Funny thing: Looks like they had the bug when they presented the new feature in iOS 10 (https://developer.apple.com/videos/play/wwdc2016/101/?time=3221)

With that implemented though, I still don't get the correct height adjustment. See relevant code details below, and for the full source code check out: https://github.com/everlof/TodayExtensionSample.

override func viewDidLoad() {
    super.viewDidLoad()
    extensionContext?.widgetLargestAvailableDisplayMode = .expanded
    view.backgroundColor = .red
    lbl.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae tempor nulla, in volutpat lectus. Sed quis orci sit amet velit cursus congue non accumsan turpis. Phasellus quis augue lobortis, pharetra arcu vitae, condimentum nunc. Nam rutrum massa ac feugiat eleifend. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non erat orci. Ut consequat faucibus sapien, et luctus magna posuere tempor."
    lbl.numberOfLines = 0
    lbl.backgroundColor = .blue
    lbl.translatesAutoresizingMaskIntoConstraints = false
}

and widgetActiveDisplayModeDidChange (which returns zero height so that it is using Auto Layout instead):

func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
    if activeDisplayMode == .expanded {
        print("EXPANDED")
        preferredContentSize = CGSize(width: 0.0, height: 0.0)
        setupLabel()
    } else if activeDisplayMode == .compact {
        print("COMPACT")
        preferredContentSize = maxSize
        setupLabel()
    }
}

and setupLabel (which removes it and adds it):

func setupLabel() {
    lbl.removeFromSuperview()
    view.addSubview(lbl)
    lbl.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 18).isActive = true
    lbl.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -18).isActive = true
    lbl.topAnchor.constraint(equalTo: view.topAnchor, constant: 18).isActive = true
    lbl.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -18).isActive = true
    lbl.setContentCompressionResistancePriority(1000, for: .vertical)
}

If the extension is STARTED in .expanded it looks correct:

if 'Show less' is pressed it looks correct:

however, if 'Show more' is pressed, then it wont expand again:

回答1:

This is because when you press "Show More", widgetActiveDisplayModeDidChange method is called with activeDisplayMode as expanded.

According to your code, in expanded mode you are setting the preferredContentSize as:

preferredContentSize = CGSize(width: 0.0, height: 0.0)

So, it takes the minimum height allowed for widget, i.e. 110.

Try this:

func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize)
{
    if activeDisplayMode == .expanded
    {
        let size = self.sampleLabel.systemLayoutSizeFitting(self.sampleLabel.bounds.size)
        preferredContentSize = CGSize(width: 0.0, height: size.height)
    }
    else
    {
        preferredContentSize = maxSize
    }
}