I have page controller which have 4 page the and in the first three the page indicator is at the bottom of the screen and in the last one I want to change it place to be in the top
func newVc(viewController: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return orderedViewControllers.last
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
guard orderedViewControllersCount != nextIndex else {
return orderedViewControllers.first
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
func configurePageControl() {
many available colors we have.
pageControl = UIPageControl(frame: CGRect(x: 0,y: UIScreen.main.bounds.maxY - 50,width: UIScreen.main.bounds.width,height: 50))
self.pageControl.numberOfPages = orderedViewControllers.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.black
self.pageControl.pageIndicatorTintColor = UIColor.white
self.pageControl.currentPageIndicatorTintColor = UIColor.black
self.view.addSubview(pageControl)
}
Change Your y position in page control frame when you reach at a particular index in the page view controller.
Try the following code:
pageControl.frame = CGRect(x: 0, y: 70, width: UIScreen.main.bounds.width, height: 50)
adjust your Y position in the frame according to your requirement.
Related
let segment : UISegmentedControl = {
let segment = UISegmentedControl.init(frame: CGRect(x: 20, y: SCREEN_HEIGHT-80, width: SCREEN_WIDTH-40, height: 40))
segment.insertSegment(with: UIImage(named: "cgtab_pay"), at: 0, animated: true)
segment.insertSegment(with: UIImage(named: "cgtab_service"), at: 0, animated: true)
segment.insertSegment(with: UIImage(named: "cgtab_chat"), at: 0, animated: true)
segment.insertSegment(with: UIImage(named: "cgtab_pay"), at: 0, animated: true)
segment.addTarget(self, action: #selector(MySegmentControlAction), for: .valueChanged)
segment.selectedSegmentIndex = 0
segment.backgroundColor = UIColor.white
return segment
}()
#objc func MySegmentControlAction(segment: UISegmentedControl) {
if(segment.selectedSegmentIndex == 0){
segment.setImage(UIImage(named: "cgtab_pay_active"), forSegmentAt: 0)
segment.setImage(UIImage(named: "cgtab_service"), forSegmentAt: 1)
segment.setImage(UIImage(named: "cgtab_chat"), forSegmentAt: 2)
segment.setImage(UIImage(named: "cgtab_pay"), forSegmentAt: 3)
let rawPay = PayViewController.init()
let payNavi = UINavigationController.init(rootViewController: rawPay)
//how to use rootViewController???
}else if(segment.selectedSegmentIndex == 1){
segment.setImage(UIImage(named: "cgtab_pay"), forSegmentAt: 0)
segment.setImage(UIImage(named: "cgtab_service_active"), forSegmentAt: 1)
segment.setImage(UIImage(named: "cgtab_chat"), forSegmentAt: 2)
segment.setImage(UIImage(named: "cgtab_pay"), forSegmentAt: 3)
}else if(segment.selectedSegmentIndex == 2){
segment.setImage(UIImage(named: "cgtab_pay"), forSegmentAt: 0)
segment.setImage(UIImage(named: "cgtab_service"), forSegmentAt: 1)
segment.setImage(UIImage(named: "cgtab_chat_active"), forSegmentAt: 2)
segment.setImage(UIImage(named: "cgtab_pay"), forSegmentAt: 3)
}else if(segment.selectedSegmentIndex == 3){
segment.setImage(UIImage(named: "cgtab_pay"), forSegmentAt: 0)
segment.setImage(UIImage(named: "cgtab_service"), forSegmentAt: 1)
segment.setImage(UIImage(named: "cgtab_chat"), forSegmentAt: 2)
segment.setImage(UIImage(named: "cgtab_pay_active"), forSegmentAt: 3)
}
}
There are multiple approaches for achieving this 2 of them are:
Child View Controllers
Add a container view below your segmented control that will be responsible for holding your child view controller's view let's say its `containerView`
lazy var controller1: UIViewController = {
return self.storyboard!.instantiateViewController(withIdentifier: "Identifier1")
}()
lazy var controller2: UIViewController = {
return self.storyboard!.instantiateViewController(withIdentifier: "Identifier2")
}()
lazy var controller3: UIViewController = {
return self.storyboard!.instantiateViewController(withIdentifier: "Identifier3")
}()
func addChildController(controller: UIViewController) {
self.addChildViewController(controller)
controller.willMove(toParentViewController: self)
self.containerView.addSubview(controller.view)
controller.view.translatesAutoresizingMaskIntoConstraints = false
controller.view.topAnchor.constraint(equalTo: self.containerView.topAnchor, constant: 0.0).isActive = true
controller.view.bottomAnchor.constraint(equalTo: self.containerView.bottomAnchor, constant: 0.0).isActive = true
controller.view.leftAnchor.constraint(equalTo: self.containerView.leftAnchor, constant: 0.0).isActive = true
controller.view.rightAnchor.constraint(equalTo: self.containerView.rightAnchor, constant: 0.0).isActive = true
}
func removeCurrentChildController() {
let currentChildController = self.childViewControllers.first
currentChildController?.removeFromParentViewController()
currentChildController?.view.removeFromSuperview()
}
#IBAction func segmentedControlValueChanged(sender: UISegmentedControl) {
self.removeCurrentChildController()
if sender.selectedSegmentIndex == 0 {
self.addChildController(controller: self.controller1)
} else if sender.selectedSegmentIndex == 1 {
self.addChildController(controller: self.controller2)
}
}
It's just a basic example. Obviously you can improve it by making it interactive. for example put the child view controllers in a scrollview so user can also swipe left/right to switch to the desired controller (Don't forget to enable paging on UIScrollView)
PageViewController
func setupPageController() {
self.pageController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: [:])
self.pageController.dataSource = self
self.pageController.delegate = self
self.addChildViewController(self.pageController)
self.pageController.willMove(toParentViewController: self)
self.contentView.addSubview(self.pageController.view)
self.pageController.view.autoPinEdgesToSuperviewEdges()
}
//MARK: UIPageViewControllerDataSource
extension OfferWalletViewController: UIPageViewControllerDataSource {
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
if let index = self.controllers.firstIndex(of: viewController), (index - 1) >= 0 {
return self.controllers[index - 1]
} else {
return nil
}
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
if let index = self.controllers.firstIndex(of: viewController), ((index + 1) < self.controllers.count) {
return self.controllers[index + 1]
} else {
return nil
}
}
}
//MARK: UIPageViewControllerDelegate
extension OfferWalletViewController: UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
debugPrint("pending controllers: \(previousViewControllers)")
}
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
debugPrint("pending controllers: \(pendingViewControllers)")
}
}
You can set your desired view controller like this:
self.pageController.setViewControllers([controller], direction: direction, animated: animated) { (completed: Bool) in
}
I have UIPageViewController with spine mid location. Now my 2 pages occupy the whole screen. But I want to change size of my flipping pages that I can create buttons in other part of controller. How to do it?
code:
import UIKit
class PageViewController: UIViewController {
#IBOutlet weak var PageControl: UIPageControl!
var pageViewController: UIPageViewController?
var images = ["book1page1.png","book1","book1","book1page2.png","book1page1.png","book1page2.png"]
var pendingIndex: Int?
override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControll()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func createPageViewController() {
// Instantiate the PageViewController
let pageController = self.storyboard?.instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController
pageController.dataSource = self
pageController.delegate = self
if images.count > 0{
let firstController = getContentViewController(withIndex: 0)!
let contentControllers = [firstController]
pageController.setViewControllers(contentControllers, direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
}
pageViewController = pageController
self.addChildViewController(pageViewController!)
//self.view.addSubview(pageViewController!.view)
self.view.insertSubview(pageViewController!.view, at: 0)
pageViewController!.didMove(toParentViewController: self)
}
//Setup Pagination Icons and count
func presentationCount(for pageViewController: UIPageViewController) -> Int {
return images.count
}
func presentationIndex(for pageViewController: UIPageViewController) -> Int {
return 0
}
func setupPageControll(){
let apperance = UIPageControl.appearance()
apperance.pageIndicatorTintColor = UIColor.gray
apperance.currentPageIndicatorTintColor = UIColor.white
apperance.backgroundColor = UIColor.clear
}
func currentControllerIndex() -> Int{
let pageItemController = self.currentConroller()
if let controller = pageItemController as? ContentViewController {
return controller.itemIndex
}
return -1
}
///////////////////////////////////////////////
func currentConroller() -> UIViewController?{
if (self.pageViewController?.viewControllers?.count)! > 0{
return self.pageViewController?.viewControllers![0]
}
return nil
}
func getContentViewController(withIndex index: Int) -> ContentViewController? {
if index < images.count{
let contentVC = self.storyboard?.instantiateViewController(withIdentifier: "ContentViewController") as! ContentViewController
contentVC.itemIndex = index
contentVC.imageName = images[index]
return contentVC
}
return nil
}
}
extension PageViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate {
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
pendingIndex = (pendingViewControllers.first as! ContentViewController).itemIndex
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
if completed {
let currentIndex = pendingIndex
if let index = currentIndex {
self.PageControl.currentPage = index
}
}
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
let contentVC = viewController as! ContentViewController
if contentVC.itemIndex > 0 {
return getContentViewController(withIndex: contentVC.itemIndex - 1)
}
return nil
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
let contentVC = viewController as! ContentViewController
if contentVC.itemIndex + 1 < images.count {
return getContentViewController(withIndex: contentVC.itemIndex + 1)
}
return nil
}
}
Here you have instantiate UIPageViewController (id:"PageViewController") and add as subview inside the UIViewController so if you want create UIButton you can create but if its want to visible in front of this UIPageViewController You can put self.view.insertSubview(pageViewController!.view, at: 0) to says your UIViewController to put this subview at index 0 (means behind the every subviews)
Below I have given code: Add Subview at index 0 and Make Size of the PageViewController using pageController.view.frame = CGRect(x: 50, y: 50, width: self.view.frame.width - (5.0 * 20.0), height: self.view.frame.height - (2.0 * 50.0)) also Added two buttons calls "Next" and "Previous' at the bottom of UIPageController
Check Blow Code:
func createPageViewController() {
let pageController = self.storyboard?.instantiateViewController(withIdentifier: "PageViewController") as! UIPageViewController
pageController.isDoubleSided = true
pageController.dataSource = self
pageController.delegate = self
if images.count > 1{
let firstController = getContentViewController(withIndex: 0)!
let secondController = getContentViewController(withIndex: 1)!
let contentControllers = [firstController,secondController]
pageController.setViewControllers(contentControllers, direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
}
pageViewController = pageController
self.addChildViewController(pageViewController!)
self.view.insertSubview(pageViewController!.view, at: 0)
pageController.view.frame = CGRect(x: 50, y: 50, width: self.view.frame.width - (5.0 * 20.0), height: self.view.frame.height - (2.0 * 50.0))
pageController.view.layer.borderColor = UIColor.lightGray.cgColor
pageController.view.layer.borderWidth = 1.0
pageViewController!.didMove(toParentViewController: self)
//Next Page Button
let nextButton = UIButton()
nextButton.frame = CGRect(x: pageController.view.frame.maxX - 75, y: pageController.view.frame.maxY + 5, width: 75, height: 50)
nextButton.backgroundColor = UIColor.blue
nextButton.setTitle("Next", for: .normal)
nextButton.addTarget(self, action: #selector(buttonActionNext), for: .touchUpInside)
self.view.addSubview(nextButton)
//Previous Page Button
let previousButton = UIButton()
previousButton.frame = CGRect(x: pageController.view.frame.minX, y: pageController.view.frame.maxY + 5, width: 75, height: 50)
previousButton.backgroundColor = UIColor.blue
previousButton.setTitle("Previous", for: .normal)
previousButton.addTarget(self, action: #selector(buttonActionPrevious), for: .touchUpInside)
self.view.addSubview(previousButton)
}
#objc func buttonActionNext(sender: UIButton!) {
print("Next page")
}
#objc func buttonActionPrevious(sender: UIButton!) {
print("Previous Page")
}
You need to change the frame
pageViewController!.view.frame = ///
self.view.insertSubview(pageViewController!.view, at: 0)
I'm trying to change the dots in page control with some images..
Here the code i have tried:
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource {
// MARK: Data source functions.
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let previousIndex = viewControllerIndex - 1
guard previousIndex >= 0 else {
return orderedViewControllers.last
// Uncommment the line below, remove the line above if you don't want the page control to loop.
// return nil
}
guard orderedViewControllers.count > previousIndex else {
return nil
}
return orderedViewControllers[previousIndex]
}
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
guard let viewControllerIndex = orderedViewControllers.index(of: viewController) else {
return nil
}
let nextIndex = viewControllerIndex + 1
let orderedViewControllersCount = orderedViewControllers.count
// the first view controller.
guard orderedViewControllersCount != nextIndex else {
return orderedViewControllers.first
// Uncommment the line below, remove the line above if you don't want the page control to loop.
// return nil
}
guard orderedViewControllersCount > nextIndex else {
return nil
}
return orderedViewControllers[nextIndex]
}
lazy var orderedViewControllers: [UIViewController] = {
return [self.newVc(viewController: "sbYellow"),
self.newVc(viewController: "sbRed"),
self.newVc(viewController: "sbBlue")]
}()
var pageControl = UIPageControl()
override func viewDidLoad() {
super.viewDidLoad()
self.dataSource = self
// This sets up the first view that will show up on our page control
if let firstViewController = orderedViewControllers.first {
setViewControllers([firstViewController],
direction: .forward,
animated: true,
completion: nil)
}
let pageControl = CustomPageControl(frame: CGRect(x: 100, y: 100, width: 104, height: 40))
pageControl.numberOfPages = 3
pageControl.currentPage = 0
self.view.addSubview(pageControl)
/*self.delegate = self
configurePageControl()*/
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func configurePageControl() {
// The total number of pages that are available is based on how many available colors we have.
pageControl = UIPageControl(frame: CGRect(x: 0,y: UIScreen.main.bounds.maxY - 50,width: UIScreen.main.bounds.width,height: 50))
self.pageControl.numberOfPages = orderedViewControllers.count
self.pageControl.currentPage = 0
self.pageControl.tintColor = UIColor.black
self.pageControl.pageIndicatorTintColor = UIColor.white
self.pageControl.currentPageIndicatorTintColor = UIColor.black
self.view.addSubview(pageControl)
}
func newVc(viewController: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
}
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
let pageContentViewController = pageViewController.viewControllers![0]
self.pageControl.currentPage = orderedViewControllers.index(of: pageContentViewController)!
}
}
class CustomPageControl: UIPageControl {
var imageToBeReplacedByDot: UIImage {
return imageLiteral(resourceName: "av_timer - material")// Image you want to
replace with dots
}
var circleImage: UIImage {
return imageLiteral(resourceName: "cancel - material")//Default Image
}
override var numberOfPages: Int {
didSet {
updateDots()
}}
override var currentPage: Int {
didSet {
updateDots()
}}
override func awakeFromNib() {
super.awakeFromNib()
self.pageIndicatorTintColor = UIColor.clear
self.currentPageIndicatorTintColor = UIColor.clear
self.clipsToBounds = false
}
func updateDots() {
var i = 0
for view in self.subviews {
var imageView = self.imageView(forSubview: view)
if imageView == nil {
if i == 0 {
imageView = UIImageView(image: imageToBeReplacedByDot)
} else {
imageView = UIImageView(image: circleImage)
}
imageView!.center = view.center
view.addSubview(imageView!)
view.clipsToBounds = false
}
if i == self.currentPage {
imageView!.alpha = 1.0
} else {
imageView!.alpha = 0.5
}
i += 1
}
}
fileprivate func imageView(forSubview view: UIView) -> UIImageView? {
var dot: UIImageView?
if let dotImageView = view as? UIImageView {
dot = dotImageView
} else {
for foundView in view.subviews {
if let imageView = foundView as? UIImageView {
dot = imageView
break
}
}
}
return dot
}
}
Which is working fine and changing the dots with images... the issue is that the image will not change if i scrolled!.. also i want to position the page control on center top of the screen..
How to achieve that?
Screenshot:
You can use this code for Reference:
import UIKit
class LocationPageControl: UIPageControl {
let locationArrow: UIImage = UIImage(named: "locationArrow")!
let pageCircle: UIImage = UIImage(named: "pageCircle")!
override var numberOfPages: Int {
didSet {
updateDots()
}
}
override var currentPage: Int {
didSet {
updateDots()
}
}
override func awakeFromNib() {
super.awakeFromNib()
self.pageIndicatorTintColor = UIColor.clear
self.currentPageIndicatorTintColor = UIColor.clear
self.clipsToBounds = false
}
func updateDots() {
var i = 0
for view in self.subviews {
var imageView = self.imageView(forSubview: view)
if imageView == nil {
if i == 0 {
imageView = UIImageView(image: locationArrow)
} else {
imageView = UIImageView(image: pageCircle)
}
imageView!.center = view.center
view.addSubview(imageView!)
view.clipsToBounds = false
}
if i == self.currentPage {
imageView!.alpha = 1.0
} else {
imageView!.alpha = 0.5
}
i += 1
}
}
fileprivate func imageView(forSubview view: UIView) -> UIImageView? {
var dot: UIImageView?
if let dotImageView = view as? UIImageView {
dot = dotImageView
} else {
for foundView in view.subviews {
if let imageView = foundView as? UIImageView {
dot = imageView
break
}
}
}
return dot
}
}
Note:- Set your image according as per your need
After I updated my iPhone to iOS 10 I noticed this very strange constraint issue with a UITextField in a UINavigationBar has appeared in my app iOS Tipped. I thought updating my Xcode project to swift 3 would fix it but the problem persists. For some reason this ins't an issue with iOS 9 and lower.
Please download my app Tipped... it's free and you will be able to see
the issue described below.
1: When I launch my app and tap the tab bar to the viewController with the textfield constraint issue in the navigation bar I get this
2: When I press another tab bar option (like the home page) the tap the search tab bar option (navigating back to the page with the issue) I get this
3: Also when I tap one of the segment buttons on the search page with the constraint issue. The constraint issue will reappear and the textfield will go too far to the right.
I have tried the below code to try to fix the problem but nothing seems to be working. Really stuck here any help would be like awesome.
override func viewWillAppear(_ animated: Bool) {
// searchTextField.becomeFirstResponder()
print("viewWillAppear: searchPageViewController")
navigationView.setNeedsLayout()
navigationView.updateConstraintsIfNeeded()
searchTextField.updateConstraints()
searchTextField.setNeedsLayout()
}
Below is the code from the viewcontroller that I am having trouble with.
class SearchPageViewController: UIPageViewController, UISearchBarDelegate, UISearchDisplayDelegate, UIPageViewControllerDataSource, UIPageViewControllerDelegate, UIScrollViewDelegate, UITextFieldDelegate {
//%%% customizeable button attributes
let X_BUFFER:CGFloat = 0.0; //%%% the number of pixels on either side of the segment
let Y_BUFFER:CGFloat = 0.0; //%%% number of pixels on top of the segment
let HEIGHT:CGFloat = 44.0; //%%% height of the segment
//%%% customizeable selector bar attributes (the black bar under the buttons)
let BOUNCE_BUFFER:CGFloat = 10.0; //%%% adds bounce to the selection bar when you scroll
let ANIMATION_SPEED:CGFloat = 0.2; //%%% the number of seconds it takes to complete the animation
let SELECTOR_Y_BUFFER:CGFloat = 40.0; //%%% the y-value of the bar that shows what page you are on (0 is the top)
let SELECTOR_HEIGHT:CGFloat = 4.0; //%%% thickness of the selector bar
let X_OFFSET:CGFloat = 0.0; //%%% for some reason there's a little bit of a glitchy offset. I'm going to look for a better workaround in the future
var navigationView = UIView()
var containerView = UIView()
var buttonText:NSArray = []
var pageScrollView:UIScrollView!
var currentPageIndex:Int!
var selectionBar = UIView()
var buttonOneTap:Bool = false
var buttonTwoTap:Bool = false
fileprivate var _controllerEnum: ControllerEnum = ControllerEnum()
fileprivate var _dict: [UIViewController: ControllerEnum] = [:]
var editView = UIView()
// var delegate: ViewControllerDelegate? = nil
// var userList = NSMutableArray()
// var searchString = String()
// var viewControllerArray:NSMutableArray = NSMutableArray()
var blogSearchCollectionViewController:BlogSearchCollectionViewController!
// var pageViewController: UIPageViewController!
var pageTitles: NSArray!
var pageImages: NSArray!
let searchController = UISearchController(searchResultsController: nil)
#IBOutlet weak var searchBarView: UIView!
#IBOutlet weak var searchTextField: UITextField!
//Stretching the searchTextField full width of navbar
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
widenTextField()
}
func widenTextField() {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: 8, height: 0))
self.searchTextField.leftView = paddingView
self.searchTextField.leftViewMode = .always
let paddingViewRight = UIView(frame: CGRect(x: 0, y: 0, width: 8, height: 0))
self.searchTextField.rightView = paddingViewRight
self.searchTextField.rightViewMode = .always
searchBarView.frame = CGRect(x: 16, y: 5, width: self.view.frame.width, height: 34)
// var frame:CGRect = self.searchTextField.frame
// frame.size.width = self.view.frame.width
// self.searchTextField.frame = CGRectMake(16, 5, self.view.frame.width, 33)
}
// TextFieldDelegates
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// textField.resignFirstResponder()
handleTap(editView)
if currentPageIndex == 0 {
let vc = self.viewControllerAtIndex(currentPageIndex) as BlogSearchCollectionViewController
// vc.loadUsers(textField.text.lowercaseString)
vc.searchText = textField.text!.lowercased()
vc.loadObjects()
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
} else if currentPageIndex == 1 {
let vc = self.viewControllerAtIndexTwo(currentPageIndex) as PhotoSearchController
vc.search(textField.text!.lowercased())
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
}
return true
}
// var lastTextFieldEdit:String!
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
showEditView()
if let text = textField.text {
if text.characters.count > 0 {
DispatchQueue.main.async{
textField.selectAll(nil)
}
}
}
searchTextField.textAlignment = NSTextAlignment.left
return true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
print(textField)
}
override func viewWillAppear(_ animated: Bool) {
// searchTextField.becomeFirstResponder()
print("viewWillAppear: searchPageViewController")
}
override func viewDidAppear(_ animated: Bool) {
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupSegmentButtons()
self.setupPage()
currentPageIndex = 0
// self.navigationItem.titleView = searchTextField
}
//Mark: SearchBar stuff
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
// searchController.searchBar.showsCancelButton = true
return true
}
func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {
searchController.searchBar.showsCancelButton = true
// for subView in searchController.view.subviews {
// if let dimView = subView as? UIView {
// dimView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.6)
// }
// }
return true
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
for subView in searchController.view.subviews {
}
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
print("hithere")
searchController.searchBar.showsCancelButton = true
// searchController.dimsBackgroundDuringPresentation = false
print("searchController.view.subviews1: - \(searchController.searchBar.subviews)")
for subView in searchController.view.subviews {
print("searchController.view.subviews2: - \(searchController.view.subviews)")
if let dimView = subView as? UIView {
dimView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.0)
}
}
// searchController.dismissViewControllerAnimated(true, completion: nil)
if currentPageIndex == 0 {
let vc = self.viewControllerAtIndex(currentPageIndex) as BlogSearchCollectionViewController
// vc.loadUsers(searchBarString.lowercaseString)
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
} else if currentPageIndex == 1 {
let vc = self.viewControllerAtIndexTwo(currentPageIndex) as PhotoSearchController
vc.search(searchBarString.lowercased())
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: .forward, animated: false, completion: nil)
}
}
var searchBarString:String!
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchController.searchBar.showsCancelButton = true
let uiButton = searchController.searchBar.value(forKey: "cancelButton") as! UIButton
uiButton.setTitle("Cancel", for: UIControlState())
uiButton.setTitleColor(UIColor.black, for: UIControlState())
uiButton.titleLabel!.font = UIFont(name: "Helvetica Neue", size: 17)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBarString = searchText
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func setupSegmentButtons() {
navigationView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: HEIGHT))
navigationView.backgroundColor = UIColor.brown
let numControllers = 2
// if buttonText == NSNotFound {
buttonText = NSArray(objects: "BLOGS", "TIPS")
// }
let buttonOne:UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width/2, height: HEIGHT))
let buttonTwo:UIButton = UIButton(frame: CGRect(x: self.view.frame.size.width/2, y: 0, width: self.view.frame.size.width/2, height: HEIGHT))
navigationView.addSubview(buttonOne)
navigationView.addSubview(buttonTwo)
buttonOne.tag = 0
buttonOne.backgroundColor = UIColor.white
buttonOne.addTarget(self, action: #selector(SearchPageViewController.tapSegmentButtonAction(_:)), for: UIControlEvents.touchUpInside)
buttonOne.setTitle(buttonText[0] as? String, for: UIControlState())
buttonOne.setTitleColor(UIColor.black, for: UIControlState())
buttonOne.titleLabel!.font = UIFont(name: "Interstate-Bold", size: 17)!
buttonTwo.tag = 1
buttonTwo.backgroundColor = UIColor.white
buttonTwo.addTarget(self, action: #selector(SearchPageViewController.tapSegmentButtonAction(_:)), for: UIControlEvents.touchUpInside)
buttonTwo.setTitle(buttonText[1] as? String, for: UIControlState())
buttonTwo.setTitleColor(UIColor.black, for: UIControlState())
buttonTwo.titleLabel!.font = UIFont(name: "Interstate-Bold", size: 17)
self.view.addSubview(navigationView)
self.setupSelector()
}
func setupSelector() {
selectionBar = UIView(frame: CGRect(x: X_BUFFER-X_OFFSET, y: SELECTOR_Y_BUFFER,width: (self.view.frame.size.width-2*X_BUFFER)/2, height: SELECTOR_HEIGHT))
selectionBar.backgroundColor = UIColor(red: 251/255, green: 73/255, blue: 90/255, alpha: 1.0)
// selectionBar.alpha = 1
navigationView.addSubview(selectionBar)
}
func setupPage() {
// self.navigationItem.titleView = searchTextField
view.backgroundColor = UIColor.white
//TextFieldStuff
searchTextField.delegate = self
searchTextField.placeholder = "Search for blogs"
searchTextField.textAlignment = NSTextAlignment.center
searchTextField.autocorrectionType = .no
//TextField is editing translucent view
editView.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.6)
editView.frame = CGRect(x: 0, /*self.navigationController!.navigationBar.frame.size.height + 20 +*/ y: HEIGHT, width: self.view.frame.size.width, height: self.view.frame.size.height - (self.navigationController!.navigationBar.frame.size.height + 20 + HEIGHT))
self.view.addSubview(editView)
editView.isHidden = true
//tapGesture
editView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SearchPageViewController.handleTap(_:)))
editView.addGestureRecognizer(tapGesture)
let pageControl = UIPageControl()
pageControl.backgroundColor = UIColor.white
self.pageTitles = NSArray(objects: "Explore", "Today Widget")
self.pageImages = NSArray(objects: "page1", "page2")
//PageViewControllers
delegate = self
dataSource = self
let vc = self.viewControllerAtIndex(0) as BlogSearchCollectionViewController
// vc.loadUsers("")
vc.searchText = ""
vc.loadObjects()
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController], direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: nil)
print("pageSetUp:- \(currentPageIndex)")
self.syncScrollView()
}
func handleTap(_ sender : UIView) {
// searchController.resignFirstResponder()
searchTextField.resignFirstResponder()
searchTextField.textAlignment = NSTextAlignment.center
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.editView.alpha = 0
}, completion: { (success:Bool) -> Void in
if success {
self.editView.isHidden = true
}
})
// UIView.animateWithDuration(0.5, animations: { () -> Void in
// self.editView.alpha = 0
// })
print("Tap Gesture recognized")
}
func showEditView() {
editView.alpha = 0
editView.isHidden = false
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.editView.alpha = 0.6
})
}
func viewControllerAtIndex(_ index: Int) -> BlogSearchCollectionViewController {
let vc: BlogSearchCollectionViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BlogSearchCollectionViewController") as! BlogSearchCollectionViewController
return vc
}
func viewControllerAtIndexTwo(_ index: Int) -> PhotoSearchController {
let vc: PhotoSearchController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoSearchController") as! PhotoSearchController
// currentPageIndex = vc.pageIndex
return vc
}
func syncScrollView() {
let x = self.view.subviews
var view:UIView!
for view in x {
if view.isKind(of: UIScrollView.self) {
pageScrollView = view as! UIScrollView
pageScrollView.delegate = self
}
}
}
//%%% when you tap one of the buttons, it shows that page,
//but it also has to animate the other pages to make it feel like you're crossing a 2d expansion,
//so there's a loop that shows every view controller in the array up to the one you selected
//eg: if you're on page 1 and you click tab 3, then it shows you page 2 and then page 3
func tapSegmentButtonAction(_ button:UIButton) {
if buttonOneTap == false && buttonTwoTap == false {
let tempIndex:Int = self.currentPageIndex
//%%% check to see if you're going left -> right or right -> left
// println("buttonTag + tempIndex \(button.tag) \(tempIndex)")
if button.tag > tempIndex {
//%%% scroll through all the objects between the two points
buttonOneTap = true
// var i = tempIndex+1
// for i in stride(from:i, through:(button.tag), by: 1) {
for tempIndex in 0..<button.tag {
// for var i = tempIndex+1; i<=button.tag; i += 1 {
// println(i)
let vc: PhotoSearchController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoSearchController") as! PhotoSearchController
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController] /*[getController(.Debts)!]viewControllerArray.objectAtIndex(i) as! [AnyObject]*/, direction: UIPageViewControllerNavigationDirection.forward, animated: true, completion: { (success:Bool) -> Void in
//%%% if the action finishes scrolling (i.e. the user doesn't stop it in the middle),
//then it updates the page that it's currently on
if success == true {
self.buttonOneTap = false
self.updateCurrentPageIndex(1)
// self.searchController.searchBar.placeholder = "Search for tips"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for tips"
self.searchTextField.placeholder = "Search for tips"
}
})
}
//%%% this is the same thing but for going right -> left
} else if button.tag < tempIndex {
buttonTwoTap = true
// var i = tempIndex+1
// for i in stride(from:i, through:(button.tag), by: -1) {
// for var i = tempIndex-1; i >= button.tag; i -= 1 {
for tempIndex in (0...button.tag).reversed() {
// println(i)
let vc: BlogSearchCollectionViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BlogSearchCollectionViewController") as! BlogSearchCollectionViewController
// vc.loadUsers("")
vc.searchText = ""
vc.loadObjects()
vc.showActivityIndicator()
let viewControllers = NSArray(object: vc)
setViewControllers(viewControllers as? [UIViewController] /*[getController(_controllerEnum)!] viewControllerArray.objectAtIndex(i) as! [AnyObject]*/, direction: UIPageViewControllerNavigationDirection.reverse, animated: true, completion: { (success:Bool) -> Void in
if success == true {
self.buttonTwoTap = false
self.updateCurrentPageIndex(0)
// self.searchController.searchBar.placeholder = "Search for blogs"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for blogs"
self.searchTextField.placeholder = "Search for blogs"
}
})
}
}
}
}
func updateCurrentPageIndex(_ newIndex:Int) {
self.currentPageIndex = newIndex
}
//%%% makes sure the nav bar is always aware of what page you're on
//in reference to the array of view controllers you gave
//%%% method is called when any of the pages moves.
var xFromCenter:CGFloat!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// println(self.currentPageIndex)
//It extracts the xcoordinate from the center point and instructs the selection bar to move accordingly
xFromCenter = self.view.frame.size.width-scrollView.contentOffset.x
print(xFromCenter)
// if xFromCenter > 0 && currentPageIndex == 0 {
// updateCurrentPageIndex(0)
// }
// println(self.currentPageIndex)
var a = X_BUFFER + selectionBar.frame.size.width
var b = CGFloat(currentPageIndex) - X_OFFSET
let xCoor = selectionBar.frame.size.width * CGFloat(self.currentPageIndex)
// println(xCoor)
//%%% checks to see what page you are on and adjusts the xCoor accordingly.
//i.e. if you're on the second page, it makes sure that the bar starts from the frame.origin.x of the
//second tab instead of the beginning
selectionBar.frame = CGRect(x: xCoor - xFromCenter/2, y: selectionBar.frame.origin.y, width: selectionBar.frame.size.width, height: selectionBar.frame.size.height)
}
// MARK: - Page View Controller Data Source
var vcOne:BlogSearchCollectionViewController!
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
var index:Int = currentPageIndex
if index == NSNotFound || index == 0 {
return nil
}
// println(currentPageIndex)
index -= 1
let vcOne = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "BlogSearchCollectionViewController") as! BlogSearchCollectionViewController
// currentPageIndex = vc.pageIndex
// println("actaulIndexBlogSearchCollectionViewController: - \(actaulIndex)")
return vcOne
// return getController(_dict[viewController]!.prevIndex())
}
var vcTwo:PhotoSearchController!
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
var index:Int = currentPageIndex
if index == NSNotFound {
return nil
}
index += 1
if index == buttonText.count {
return nil
}
vcTwo = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "PhotoSearchController") as! PhotoSearchController
// currentPageIndex = vc.pageIndex
// if vc.pageIndex == 1 && index == 0 {
// return vc
// }
// println("actaulIndexPhotoSearchController: - \(actaulIndex)")
return vcTwo
// return getController(_dict[viewController]!.nextIndex())
}
var actaulIndex:Int!
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
print("finished: - \(finished)")
print("completed: - \(completed)")
if finished == true && completed == true {
print("currentPageIndex: - \(currentPageIndex)")
if finished == true && completed == true && currentPageIndex == 0 && xFromCenter < 0 {
print("hi")
// searchController.searchBar.placeholder = "Search for tips"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for tips"
searchTextField.placeholder = "Search for tips"
updateCurrentPageIndex(1)
} else if finished == true && completed == true && currentPageIndex == 1 && xFromCenter > 0 {
print("hi 2")
// searchController.searchBar.placeholder = "Search for blogs"
// let txtField = self.navigationItem.titleView as! UITextField
// txtField.placeholder = "Search for blogs"
searchTextField.placeholder = "Search for blogs"
updateCurrentPageIndex(0)
}
}
}
}
I figured it out. Inside the widen textfield function. I needed to change the following line:
searchBarView.frame = CGRect(x: 16, y: 5, width: self.view.frame.width, height: 34)
to
searchBarView.frame = CGRect(x: 8, y: 5, width: self.view.frame.width - 16, height: 34)
I have implemented an UIScrollView & UIpageControl to display 3 UIViewControllers.
It works very well but I want to start the display on the 2nd UIViewController.
I didn't find yet where is my fault:
var pageControl:UIPageControl!
var scrollView:UIScrollView!
var viewtest1:UIViewController!
var viewtest2:UIViewController!
var viewtest3:UIViewController!
override func viewDidLoad() {
super.viewDidLoad()
// Initialization of UIScrollView
self.scrollView = UIScrollView()
self.scrollView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.scrollView.pagingEnabled = true
self.scrollView.scrollEnabled = true
self.scrollView.showsHorizontalScrollIndicator = false
self.scrollView.showsVerticalScrollIndicator = false
self.scrollView.delegate = self
// Initialisation of UIPageControl
self.pageControl = UIPageControl()
pageControl.currentPageIndicatorTintColor = UIColor(red:0.325, green:0.667, blue:0.922, alpha: 1)
pageControl.pageIndicatorTintColor = UIColor.whiteColor()
pageControl.backgroundColor = UIColor.clearColor()
// Add different view to the screen in the order from left to right
self.addChildViewController(self.viewtest1)
self.addChildViewController(self.viewtest2)
self.addChildViewController(self.viewtest3)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
for var i=0; i < self.childViewControllers.count; i++ {
self.loadScrollViewWithPage(i)
}
self.pageControl.currentPage = 0
self.page = 0
self.pageControl.numberOfPages = self.childViewControllers.count
var viewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
if viewController.view.superview != nil {
viewController.viewWillAppear(true)
}
self.scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * CGFloat(self.childViewControllers.count), scrollView.frame.size.height)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// Load Controllers
var viewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
if viewController.view.superview != nil {
viewController.viewDidAppear(true)
}
}
override func viewWillDisappear(animated: Bool) {
var viewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
if viewController.view.superview != nil {
viewController.viewWillDisappear(true)
}
super.viewWillDisappear(true)
}
override func viewDidDisappear(animated: Bool) {
var viewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
if viewController.view.superview != nil {
viewController.viewDidDisappear(true)
}
super.viewDidDisappear(true)
}
func loadScrollViewWithPage(page:Int){
if page < 0 || page >= self.childViewControllers.count {
return
}
let controller:UIViewController = self.childViewControllers[page] as! UIViewController
if (controller == false) {
return
}
// add the controller's view to the scroll view
if (controller.view.superview == nil) {
var frame:CGRect = self.scrollView.frame
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0
controller.view.frame = frame
self.scrollView.addSubview(controller.view)
}
}
func changePage(sender:AnyObject) -> () {
var senderControl:UIPageControl = sender as! UIPageControl
var page:Int = Int(senderControl.currentPage)
// update the scroll view to the appropriate page
var frame:CGRect = self.scrollView.frame
frame.origin.x = frame.size.width * CGFloat(page)
frame.origin.y = 0
var oldViewController:UIViewController = self.childViewControllers[self.page] as! UIViewController
var newViewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
oldViewController.viewWillDisappear(true)
newViewController.viewWillAppear(true)
self.scrollView.scrollRectToVisible(frame, animated: true)
self.pageControlUsed = true
}
override func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
var oldViewController:UIViewController = self.childViewControllers[self.page] as! UIViewController
var newViewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
oldViewController.viewWillDisappear(true)
newViewController.viewWillAppear(true)
self.page = self.pageControl.currentPage
}
override func scrollViewDidScroll(scrollView: UIScrollView) {
if (self.pageControlUsed == true /*|| _rotating*/) {
// do nothing - the scroll was initiated from the page control, not the user dragging
return
}
var pageWidth:CGFloat = self.scrollView.frame.size.width
var page:Int = Int(floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1)
if (self.pageControl.currentPage != page) {
var oldViewController:UIViewController = self.childViewControllers[self.pageControl.currentPage] as! UIViewController
var newViewController:UIViewController = self.childViewControllers[page] as! UIViewController
oldViewController.viewWillDisappear(true)
newViewController.viewWillDisappear(true)
self.pageControl.currentPage = page
oldViewController.viewDidDisappear(true)
newViewController.viewDidDisappear(true)
self.page = page;
}
}
override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
self.pageControlUsed = false
}
override func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
self.pageControlUsed = false
}
Thank you for your help
In storyboard set the "viewtest2" to "Is Initial View Controller". That will show that viewController first.
Or you can try in appDelegate :
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject :AnyObject]?) -> Bool {
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
var storyboard = UIStoryboard(name: "Main", bundle: nil)
var initialViewController = storyboard.instantiateViewControllerWithIdentifier("viewTest2") as UIViewController
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}