Closed Jinkeycode closed 5 years ago
It looks like if you wrap tabbarView inside one more UIView and set that view as the titleView it works.
let wrapperView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 80, height: 44))
let tabbarView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 80, height: 44))
self.embedBar(in: tabbarView)
wrapperView.addSubview(tabbarView)
self.navigationItem.titleView = wrapperView
// embed the tab bar into navigationbar
guard let navigationBar = navigationController?.navigationBar else { return }
// we margin title to the left/right item with 60
let customV = UIView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: navigationBar.bounds.width - 60.0 * 2.0, height: navigationBar.bounds.height)))
let titleV = UIView()
titleV.frame = customV.bounds
customV.addSubview(titleV)
self.embedBar(in: titleV)
self.navigationItem.titleView = customV
@craigphares It works. Thanks.
It comes problems in my app's usage in navigationItem's titleView with this library.
My titleView has a left and right bar button item.
And I embed it just like what I code above.
It works for me to show menu.
But sometimes when I scroll or switch, the titleView changes its position(frame: origin.x and size.width changes).
And when I push into another controller and pop back, the menu changes position too.
I added a strong frame control over viewDidAppear
.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
adjustTitleView()
}
private func adjustTitleView() {
guard let navigationBar = navigationController?.navigationBar else { return }
// we margin title to the left/right item with 60
self.customTitleV.frame = CGRect(origin: CGPoint(x: 60, y: 0), size: CGSize(width: navigationBar.bounds.width - 60.0 * 2.0, height: navigationBar.bounds.height))
}
But it comes another problem.
When I push and pop back, and then switch for pages, the titleView's frame changes too.
I do not know what happened.
I need to update the frame always in viewDidLayoutSubviews
.
But user could see the position changes in my app.
It's not friendly.
It has been solved for my usage. I deleted bar button items which are from storyboard. All left/right bar button items are created with code.
It's suggested not to use it in titleView. I got many problems I just do not know how to solve it. Sometimes when I add a new page, or add a new item, then the layout goes wrong.
What I do now is to hide my nav bar.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: false)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: animated)
}
@wakaryry we are successfully using Tabman in the navigationBar titleView. This seems like a real use case for this library, and it should be supported.
We're doing the same thing you mentioned previously: configuring the bar on every viewWillAppear call. We also re-declare the constraints at that moment. For the titleView, we use a custom UIView that automatically expands to fit its container frame. We have a left menuButton that we manually add to the customBarView each time. We're using SnapKit in the code below, but this could be done with any constraints technique.
// TitleView.swift
class TitleView: UIView {
override var intrinsicContentSize: CGSize {
return UIView.layoutFittingExpandedSize
}
}
// ViewController.swift
class ViewController: TabmanViewController, PageboyViewControllerDataSource {
...
lazy private var menuButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "menu"), for: .normal)
return button
}()
let titleView = TitleView()
let customBarView = UIView()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
configureBar()
}
private func configureBar() {
self.embedBar(in: customBarView)
titleView.addSubview(customBarView)
customBarView.addSubview(menuButton)
navigationItem.titleView = titleView
customBarView.snp.makeConstraints { (make) in
make.left.equalToSuperview()
make.right.equalToSuperview().offset(16)
make.top.equalToSuperview()
make.bottom.equalToSuperview()
}
menuButton.snp.makeConstraints { (make) in
make.left.equalToSuperview().offset(8)
make.width.equalTo(self.menuInset)
make.top.equalToSuperview()
make.bottom.equalToSuperview()
}
}
...
}
Hope this helps.
@craigphares Thanks for your nice work. It really helps much.
class TitleView: UIView {
override var intrinsicContentSize: CGSize {
return UIView.layoutFittingExpandedSize
}
}
Controller:
override func viewDidLoad() {
super.viewDidLoad()
buildPages()
}
private func buildPages() {
self.automaticallyAdjustsChildViewInsets = true
self.dataSource = self
self.bar.items = [
Item(title: "Mine"),
Item(title: "Discovery"),
Item(title: "Service")
]
self.bar.style = .buttonBar
self.bar.appearance = TabmanBar.Appearance({ (appearance) in
appearance.style.background = TabmanBar.BackgroundView.Style.clear
// center the indicator
//appearance.layout.interItemSpacing = 0.0
//appearance.layout.edgeInset = 0.0
})
self.configureBar()
}
private func configureBar() {
self.embedBar(in: self.tabsView)
self.titleView.addSubview(self.tabsView)
// left/rightItem: UIButton
self.titleView.addSubview(self.leftItem)
self.titleView.addSubview(self.rightItem)
self.navigationItem.titleView = self.titleView
self.tabsView.snp.makeConstraints { (make) in
make.left.equalToSuperview().offset(60)
make.right.equalToSuperview().offset(-60)
make.top.bottom.equalToSuperview()
}
self.leftItem.snp.makeConstraints { (make) in
make.left.equalToSuperview().offset(8)
make.width.equalTo(30)
make.top.bottom.equalToSuperview()
}
self.rightItem.snp.makeConstraints { (make) in
make.right.equalToSuperview().offset(-8)
make.width.equalTo(30)
make.top.bottom.equalToSuperview()
}
}
I config all in viewDidLoad
.
But with a little problem: The indicator does not show since I scroll the pages.
Does anyone get a titleView usage for the latest? Thanks.
I've tried to use your implementation @craigphares and @wakaryry but I get an error for self.embedBar
is there another way you can ember the TabmanBar to the navigation controller so that it is hidden when scrolling down?
@BeIllegalBeagle https://github.com/uias/Tabman/issues/370
@wakaryry where should I look for the unwanted constraints that maybe added?
@BeIllegalBeagle It could be solved in 2.3.0
After setting .selectedFont with a large size, such as UIFont.boldSystemFont(ofSize: 21.0), the text cannot be display fully. How can I solve it?
@Jinkeycode is this just using the current release of Tabman or are you using the new unreleased APIs in the 2.4.0
branch?
@msaps I use 2.3.0 release version
This is now natively supported in Tabman with 2.4.0 🎉
Available via BarLocation.navigationItem(item:)
- and should be called in viewWillAppear
.
addBar(bar, dataSource: self, at: .navigationItem(item: navigationItem))
Checkout the Adding a Bar docs for more info 😄.
cc @Jinkeycode @wakaryry @BeIllegalBeagle
New Issue Checklist
Issue Description
This is my code, I used
embedBar
to do it, but it wasn't work!Other useful things