Auto-link iOS 11 UIBarButtonItem Toolbar with customView

Recently in our project there was a problem with the UIBarButtonItem that used customView. Before iOS 11, we made a layout using flexible elements. This did not work anymore, so nothing was displayed.

Because I did not find here an answer to SO that really solved the problem for me, I looked into it and came up with a (admittedly hacky) solution that I wanted to share with you.

Perhaps this may help you or you have some feedback. This is mixed code and fast code, hope you don't mind.

+2
source share
1 answer

WWDC iOS 11:

", iOS 11 UI ".

, , :

    UIBarButtonItem *barButtonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
    [barButtonItem.customView.widthAnchor constraintEqualToConstant:375].active = YES;
    [barButtonItem.customView.heightAnchor constraintEqualToConstant:44].active = YES;

, . , . . , " " , UIToolbarContentView. contentView ( ), . subview, contentView, UIBarButtonStackView. stackView - customView .

, :

contentView |<-fullWidth-------->|
stackView     |<-reducedWidth->|
customView    |<-reducedWidth->|

, , customView stackView. , , customView UIBarButtonItem. () customView ( , ).

UIToolbar:

extension UIToolbar {
    private var contentView: UIView? {
        return subviews.find { (view) -> Bool in
            let viewDescription = String(describing: type(of: view))
            return viewDescription.contains("ContentView")
        }
    }

    private var stackView: UIView? {
        return contentView?.subviews.find { (view) -> Bool in
            let viewDescription = String(describing: type(of: view))
            return viewDescription.contains("ButtonBarStackView")
        }
    }

   func fitContentViewToToolbar() {
        guard let stackView = stackView, let contentView = contentView else { return }
        stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        stackView.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true

    }
}

, : contentView , "ContentView" stackView, contentView. , return subviews.first , .

voila: .

, - . : . , - , .

: "" . filter.first :

extension Sequence {
    func find(_ isIncluded: (Self.Element) throws -> Bool) rethrows -> Self.Element? {
        return try filter(isIncluded).first
}

}

+8

Source: https://habr.com/ru/post/1686733/


All Articles