Re: UINavigationBar content margins in UIPresentationController subclass
Re: UINavigationBar content margins in UIPresentationController subclass
- Subject: Re: UINavigationBar content margins in UIPresentationController subclass
- From: David Duncan <email@hidden>
- Date: Wed, 07 Dec 2016 11:05:10 -0800
The most relevant looking bug I can find seems to involve pushing & popping view controllers. That said, setting the preferredContentSize on the navigation controller directly should always work.
Alternatively you could use your own container view controller instead.
> On Dec 7, 2016, at 10:42 AM, Daniel Stenmark <email@hidden> wrote:
>
> Thanks, David. Unfortunately, UINavigationController isn’t currently an option as it doesn’t reliably bubble up preferredContentSize changes, which we have a strong dependency on and is fairly dynamic in our use case. As of 10.0, it only seems to adapt and forward the very first preferredContentSize mutation, silencing the rest. I’ve been told this is currently filed as a Radar (though, if you can confirm that’s NOT the case, I’d be more than happy to file a new one!).
>
> Is there another way I can work around this limitation in the meantime?
>
> Dan
>
>> On Dec 7, 2016, at 10:35 AM, David Duncan <email@hidden <mailto:email@hidden>> wrote:
>>
>>
>>> On Dec 7, 2016, at 10:28 AM, Daniel Stenmark <email@hidden <mailto:email@hidden>> wrote:
>>>
>>> The UINavigationBar is in the UIPresentationController’s containerView, which is a subview of the current UIWindow and does NOT have a view controller in its hierarchy. Is there a particular reason for UINavigationBar to have this dependency for correct layout? Is there a ‘right’ way to work around this aside from manual/artificial padding?
>>
>> Only view controllers know the proper calculation for the padding to be used by the bars. Typically a solution to your issue would be to wrap the presenting view controller in a UINavigationController rather than making the navigation bar part of the presentation itself.
>>
>>>
>>> Dan
>>>
>>>> On Dec 7, 2016, at 10:01 AM, David Duncan <email@hidden <mailto:email@hidden>> wrote:
>>>>
>>>> Its unclear to me at least, but where in the view hierarchy is the UINavigationBar? If it isn’t in a view that is ultimately backed by a view controller, then it won’t have the correct information to do its layout.
>>>>
>>>>> On Nov 7, 2016, at 12:42 PM, Daniel Stenmark <email@hidden <mailto:email@hidden>> wrote:
>>>>>
>>>>> I have a UIPresentationController subclass with a UINavigationBar embedded in the container view. However, when setting the rightBarButtonItem, the spacing I usually expect from the item to the screen isn't there.
>>>>>
>>>>> http://imgur.com/LHcqhyd<http://imgur.com/a/610al> <http://imgur.com/LHcqhyd>
>>>>>
>>>>> Anyone have an idea where I might be going wrong here? The relevant code for the presentation controller is as follows:
>>>>>
>>>>> @objc public protocol SheetPresentationControllerDelegate : class {
>>>>> func sheetPresentationControllerWillDismiss(_ sheetPresentationController: SheetPresentationController)
>>>>> }
>>>>>
>>>>> open class SheetPresentationController: UIPresentationController {
>>>>>
>>>>>
>>>>>
>>>>> fileprivate let dimmedView: UIView = {
>>>>> let result = UIView()
>>>>> result.backgroundColor = .black
>>>>> result.alpha = 0
>>>>> result.autoresizingMask = [.flexibleWidth, .flexibleHeight]
>>>>> return result
>>>>> }()
>>>>>
>>>>>
>>>>>
>>>>> fileprivate let topView: UIView = {
>>>>> let result = UIView()
>>>>> result.backgroundColor = .white
>>>>> return result
>>>>> }()
>>>>>
>>>>>
>>>>>
>>>>> fileprivate let navigationBar: UINavigationBar = {
>>>>> let result = UINavigationBar()
>>>>> result.backgroundColor = .white
>>>>> result.items = [UINavigationItem()]
>>>>> return result
>>>>> }()
>>>>>
>>>>>
>>>>>
>>>>> open var title: String? {
>>>>> get {
>>>>> return self.navigationBar.topItem?.title
>>>>> }
>>>>> set {
>>>>> self.navigationBar.topItem?.title = newValue
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> open var titleView: UIView? {
>>>>> get {
>>>>> return self.navigationBar.topItem?.titleView
>>>>> }
>>>>> set {
>>>>> self.navigationBar.topItem?.titleView = newValue
>>>>> }
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> open weak var sheetDelegate: SheetPresentationControllerDelegate?
>>>>>
>>>>>
>>>>>
>>>>> fileprivate dynamic func dismiss(_ sender: NSObject) {
>>>>> self.presentingViewController.dismiss(animated: true, completion: nil)
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> override open func presentationTransitionWillBegin() {
>>>>> super.presentationTransitionWillBegin()
>>>>>
>>>>>
>>>>>
>>>>> guard let containerView = self.containerView else {
>>>>> return
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> containerView.addSubview(self.dimmedView)
>>>>> self.dimmedView.frame = CGRect(origin: .zero, size: containerView.bounds.size)
>>>>>
>>>>>
>>>>>
>>>>> let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismiss))
>>>>> self.dimmedView.addGestureRecognizer(gestureRecognizer)
>>>>>
>>>>>
>>>>>
>>>>> self.presentedViewController.transitionCoordinator?.animate( alongsideTransition: { (context) in
>>>>> self.dimmedView.alpha = 0.5
>>>>>
>>>>>
>>>>>
>>>>> }, completion: nil)
>>>>>
>>>>>
>>>>>
>>>>> containerView.addSubview(self.topView)
>>>>> containerView.addSubview(self.navigationBar)
>>>>>
>>>>>
>>>>>
>>>>> self.navigationBar.topItem?.rightBarButtonItems = [UIBarButtonItem(title: NSLocalizedString("Done", comment: ""), style: .done, target: self, action: #selector(dismiss))]
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> override open func dismissalTransitionWillBegin() {
>>>>> super.dismissalTransitionWillBegin()
>>>>>
>>>>>
>>>>>
>>>>> self.sheetDelegate?.sheetPresentationControllerWillDismiss(self)
>>>>>
>>>>>
>>>>>
>>>>> self.presentedViewController.transitionCoordinator?.animate( alongsideTransition: { (context) in
>>>>> self.dimmedView.alpha = 0
>>>>>
>>>>>
>>>>>
>>>>> }, completion: nil)
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> override open var frameOfPresentedViewInContainerView : CGRect {
>>>>> return CGRect(x: 0, y: self.navigationBar.frame.origin.y + self.navigationBar.intrinsicContentSize.height, width: self.containerView?.bounds.width ?? 0, height: self.presentedViewController.preferredContentSize.height)
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> override open func containerViewWillLayoutSubviews() {
>>>>> super.containerViewWillLayoutSubviews()
>>>>>
>>>>>
>>>>>
>>>>> self.topView.frame = CGRect(x: 0, y: 0, width: self.containerView?.bounds.width ?? 0, height: self.presentingViewController.topLayoutGuide.length)
>>>>> self.navigationBar.frame = CGRect(x: 0, y: self.topView.frame.origin.y + self.topView.bounds.height, width: self.containerView?.bounds.width ?? 0, height: self.navigationBar.intrinsicContentSize.height)
>>>>>
>>>>>
>>>>>
>>>>> self.presentedView?.frame = self.frameOfPresentedViewInContainerView
>>>>> }
>>>>> }
>>>>>
>>>>> Dan
>>>>> _______________________________________________
>>>>>
>>>>> Cocoa-dev mailing list (email@hidden <mailto:email@hidden>)
>>>>>
>>>>> Please do not post admin requests or moderator comments to the list.
>>>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com <http://lists.apple.com/>
>>>>>
>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>
>>>>> This email sent to email@hidden <mailto:email@hidden>
>>>>
>>>> --
>>>> David Duncan
>>>
>>
>> --
>> David Duncan
>>
>
--
David Duncan
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden