Closed Smiller193 closed 5 years ago
I was about to open a new issue too about this problem? I don't want it to load like that though! How can we achieve this?
Yeah, this is the expected behaviour if you are talking about loading the next view controllers? This is the same way that UIPageViewController
works. It's initializing the previous and next view controllers in order prevent any lag when the user starts swiping to the next item.
@rechsteiner can i ask another question or do I have to open up a whole different issue
No, feel free to ask here. What's up? 🙂
@rechsteiner This is the current setup that i have for my menu items
class MainViewController: UIViewController,ContentViewControllerDelegate {
fileprivate let items = [
ImageItem(index: 1, title: "City", headerImage: UIImage(named: "city")!),
ImageItem(index: 2, title: "Concert", headerImage: UIImage(named: "concert")!),
ImageItem(index: 4, title: "Sports", headerImage: UIImage(named: "sports")!),
ImageItem(index: 5, title: "University", headerImage: UIImage(named: "university")!)
]
let pagingViewController = CustomPagingViewController()
let customLeftBar = LocationManager()
var placesClient = GMSPlacesClient()
private let menuInsets = UIEdgeInsets(top: 12, left: 5, bottom: 12, right: 5)
private let menuItemSize = CGSize(width: 85, height: 70)
private var menuHeight: CGFloat {
return menuItemSize.height + menuInsets.top + menuInsets.bottom
}
var savedLocation: CLLocation?
var lastSelectedDate: Date?
var finalCategoryEvents:[String:[Event]] = [:]
var featuredEvents:[String:[Event]] = [:]
let dateFormatter = DateFormatter()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = false
}
@objc func setupViews(){
view.backgroundColor = .white
setupBarButtonItems()
setupPagingController()
grabUserLocation()
}
private func calculateMenuHeight(for scrollView: UIScrollView) -> CGFloat {
// Calculate the height of the menu view based on the scroll view
// content offset.
let maxChange: CGFloat = 30
let offset = min(maxChange, scrollView.contentOffset.y + menuHeight) / maxChange
let height = menuHeight - (offset * maxChange)
return height
}
private func updateMenu(height: CGFloat) {
guard let menuView = pagingViewController.view as? CustomPagingView else { return }
// Update the height constraint of the menu view.
menuView.menuHeightConstraint?.constant = height
// Update the size of the menu items.
pagingViewController.menuItemSize = .fixed(
width: menuItemSize.width,
height: height - menuInsets.top - menuInsets.bottom
)
// Invalidate the collection view layout and call layoutIfNeeded
// to make sure the collection is updated.
pagingViewController.collectionViewLayout.invalidateLayout()
pagingViewController.collectionView.layoutIfNeeded()
}
/// Calculate the menu offset based on the content offset of the
/// scroll view.
private func menuOffset(for scrollView: UIScrollView) -> CGFloat {
return min(pagingViewController.options.menuHeight, max(0, scrollView.contentOffset.y))
}
func contentViewControllerDidScroll(menuFeed : MenuFeedController) {
if let menuView = pagingViewController.view as? CustomPagingView {
menuView.menuTopConstraint?.constant = -menuOffset(for: menuFeed.collectionView)
}
let height = calculateMenuHeight(for: menuFeed.collectionView)
updateMenu(height: height)
}
@objc func setupPagingController(){
pagingViewController.menuItemSource = .class(type: ImagePagingCell.self)
pagingViewController.menuItemSize = .fixed(width: menuItemSize.width, height: menuItemSize.height)
pagingViewController.menuItemSpacing = 8
pagingViewController.menuInsets = menuInsets
pagingViewController.borderColor = UIColor(white: 0, alpha: 0.1)
pagingViewController.indicatorColor = UIColor.rgb(red: 44, green: 152, blue: 229)
pagingViewController.contentInteraction = .none
pagingViewController.indicatorOptions = .visible(
height: 1,
zIndex: Int.max,
spacing: UIEdgeInsets.zero,
insets: UIEdgeInsets.zero)
pagingViewController.borderOptions = .visible(
height: 1,
zIndex: Int.max - 1,
insets: UIEdgeInsets(top: 0, left: 18, bottom: 0, right: 18))
addChildViewController(pagingViewController)
view.addSubview(pagingViewController.view)
pagingViewController.view.snp.makeConstraints { (make) in
make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
make.left.right.equalTo(view.safeAreaLayoutGuide)
make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottom)
}
pagingViewController.didMove(toParentViewController: self)
// Set our custom data source.
pagingViewController.dataSource = self
pagingViewController.delegate = self
// Set the first item as the selected paging item.
pagingViewController.select(index: 0)
}
@objc func setupBarButtonItems(){
let sideMenuButton = UIBarButtonItem(image: UIImage(named: "icons8-Menu-48")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(self.rightBarPressed))
let calendarButton = UIBarButtonItem(image: UIImage(named: "icons8-calendar-50")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(self.presentCalendar))
navigationItem.rightBarButtonItems = [sideMenuButton,calendarButton]
}
//will present the dropdown/side menu
@objc func rightBarPressed(){
print("right bar tapped")
self.sideMenuController?.revealMenu(animated: true, completion: nil)
}
//will present search vc
@objc func leftBarPressed(){
print("left bar tapped")
let searchController = PlacesSearchController()
searchController.mainVC = self
self.navigationController?.pushViewController(searchController, animated: false)
}
//will present the calendar
@objc func presentCalendar(){
print("calendar pressed")
let calendar = CalendarViewController()
if let lastDate = lastSelectedDate {
calendar.passedDate = lastDate
}
calendar.mainVC = self
calendar.savedLocation1 = self.savedLocation
self.navigationController?.pushViewController(calendar, animated: false)
}
}
extension MainViewController: PagingViewControllerDataSource {
func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, viewControllerForIndex index: Int) -> UIViewController {
let menu = MenuFeedController()
menu.featuredEvents = self.featuredEvents[items[index].title.lowercased()]
menu.finalCategoryEvents = self.finalCategoryEvents[items[index].title.lowercased()]
let menuHeight = pagingViewController.options.menuHeight
let insets = UIEdgeInsets(top: menuHeight, left: 0, bottom: 0, right: 0)
menu.collectionView.contentInset = insets
menu.ContentViewControllerDelegate = self
menu.collectionView.scrollIndicatorInsets = insets
menu.rootRef = self
return menu
}
func pagingViewController<T>(_ pagingViewController: PagingViewController<T>, pagingItemForIndex index: Int) -> T {
return items[index] as! T
}
func numberOfViewControllers<T>(in: PagingViewController<T>) -> Int{
return items.count
}
}
It works good on phones with a smaller width like the iphone X, or the iphone 7 or iphone 8. However when I go to screens with a bigger width like the plus models it looks like this.
Is there anyway to get to adapt to the screen size so there isn't that random white space there. Other than that everything else is good.
Yes, you can use sizeToFit
as your menuItemSize
. If you change this line:
pagingViewController.menuItemSize = .fixed(width: menuItemSize.width, height: menuItemSize.height)
To:
pagingViewController.menuItemSize = .sizeToFit(minWidth: menuItemSize.width, height: menuItemSize.height)
I'm pretty sure it should work 🙂
nope still looks the same I changed it in the setupPagingController function @rechsteiner still has space to the right
maybe it is due to the insets let me try to change that update: that didn't work
Are you also using sizeToFit
in your updateMenu function?
no im not let me try that @rechsteiner
that fixed it
Awesome!
Im not sure if this is an error or not but is the library supposed to load two indexes at a time? Everytime I select one it loads the index right next to it. For example if i select index 1 it loads the content for index 2. Is this library supposed to load so many times?