How do I get the index out of the optional func didMoveToPage? - ios

I am using uacaps/CAPSPageMenu in my app and I cannot figure out how to get the number of the active page so I can show a webpage corresponding to the page. In the code CAPSPageMenu.swift the following code is used.
import UIKit
#objc public protocol CAPSPageMenuDelegate {
// MARK: - Delegate functions
optional func willMoveToPage(controller: UIViewController, index: Int)
optional func didMoveToPage(controller: UIViewController, index: Int)
}
I think the index: Int part in the optional func didMoveToPage is giving me a number of the current page. Is this right? How do I get that index number in the ViewController.swift code?
EDIT
In CAPSPageMenu I found this code.
public func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
if scrollView.isEqual(controllerScrollView) {
// Call didMoveToPage delegate function
let currentController = controllerArray[currentPageIndex]
delegate?.didMoveToPage?(currentController, index: currentPageIndex)
The ViewController.swift code as shown below.
//
// ViewController.swift
// PageMenuDemoStoryboard
//
// Created by Niklas Fahl on 12/19/14.
// Copyright (c) 2014 CAPS. All rights reserved.
//
import UIKit
var websiteArray = ["http://website_0", "http://website_1", "http://website_2"]
//class ViewController: UIViewController {
class ViewController: UIViewController,CAPSPageMenuDelegate {
var pageMenu : CAPSPageMenu?
var pageNumber = 0
#IBOutlet weak var showWebsite: UIWebView!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// MARK: - UI Setup
self.title = "App Title"
self.navigationController?.navigationBar.barTintColor = UIColor(red: 30.0/255.0, green: 30.0/255.0, blue: 30.0/255.0, alpha: 1.0)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController?.navigationBar.barStyle = UIBarStyle.Black
self.navigationController?.navigationBar.tintColor = UIColor.whiteColor()
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.orangeColor()]
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "<-", style: UIBarButtonItemStyle.Done, target: self, action: "didTapGoToLeft")
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "->", style: UIBarButtonItemStyle.Done, target: self, action: "didTapGoToRight")
// MARK: - Scroll menu setup
// Initialize view controllers to display and place in array
var controllerArray : [UIViewController] = []
let controller1 : TestCollectionViewController = TestCollectionViewController(nibName: "TestCollectionViewController", bundle: nil)
controller1.title = "Item_0"
controller1.photoNameArray = ["Item_0.png"]
controllerArray.append(controller1)
let controller2 : TestCollectionViewController = TestCollectionViewController(nibName: "TestCollectionViewController", bundle: nil)
controller2.title = "Item_1"
controller2.photoNameArray = ["Item_1.png"]
controllerArray.append(controller2)
let controller3 : TestCollectionViewController = TestCollectionViewController(nibName: "TestCollectionViewController", bundle: nil)
controller3.title = "Item_2"
controller3.photoNameArray = ["Item_2.png"]
controllerArray.append(controller3)
// Customize menu (Optional)
let parameters: [CAPSPageMenuOption] = [
.ScrollMenuBackgroundColor(UIColor(red: 30.0/255.0, green: 30.0/255.0, blue: 30.0/255.0, alpha: 1.0)),
.ViewBackgroundColor(UIColor(red: 20.0/255.0, green: 20.0/255.0, blue: 20.0/255.0, alpha: 1.0)),
.SelectionIndicatorColor(UIColor.orangeColor()),
.BottomMenuHairlineColor(UIColor(red: 70.0/255.0, green: 70.0/255.0, blue: 80.0/255.0, alpha: 1.0)),
.MenuItemFont(UIFont(name: "HelveticaNeue", size: 13.0)!),
.MenuHeight(30.0),
.MenuItemWidth(90.0),
.CenterMenuItems(true)
]
// Initialize scroll menu
pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRectMake(0.0, self.view.frame.height * 0.71, self.view.frame.width, self.view.frame.height * 0.33), pageMenuOptions: parameters)
self.addChildViewController(pageMenu!)
self.view.addSubview(pageMenu!.view)
pageMenu!.didMoveToParentViewController(self)
pageMenu!.delegate = self
func willMoveToPage(controller: UIViewController, index: Int) {
let subview=controller as! ViewController
subview.pageNumber=index;
}
}
func didTapGoToLeft() {
var currentIndex = pageMenu!.currentPageIndex
if currentIndex > 0 {
pageMenu!.moveToPage(currentIndex - 1)
}
setWebPage()
}
func didTapGoToRight() {
var currentIndex = pageMenu!.currentPageIndex
if currentIndex < pageMenu!.controllerArray.count {
pageMenu!.moveToPage(currentIndex + 1)
}
setWebPage()
}
func setWebPage() {
var currentIndex = pageMenu!.currentPageIndex
switch currentIndex {
case 0:
let url = NSURL (string: "\(websiteArray[0])");
let requestObj = NSURLRequest(URL: url!);
showWebsite.loadRequest(requestObj);
break
case 1:
let url = NSURL (string: "\(websiteArray[1])");
let requestObj = NSURLRequest(URL: url!);
showWebsite.loadRequest(requestObj);
break
case 2:
let url = NSURL (string: "\(websiteArray[2])");
let requestObj = NSURLRequest(URL: url!);
showWebsite.loadRequest(requestObj);
break
default:
break
}
}
// MARK: - Container View Controller
override func shouldAutomaticallyForwardAppearanceMethods() -> Bool {
return true
}
override func shouldAutomaticallyForwardRotationMethods() -> Bool {
return true
}
}
When I tap the buttons it is working like it should. The navigation bar shows the active page and the picture (collectionViewController) that belongs to the active page is shown and also the webpage that belongs to the active page is shown. But I do not want to use the buttons. I want to use the collectionViewController so that when I swipe the image to the next page the new image is shown (this is working already) and the corresponding webpage also (this is not working because of not setting the pageMenu!.currentPageIndex).
How to activate the didTapGoToLeft and Right methods when I swipe the picture?

The CAPSPageMenu provides a delegate method that inform's its delegate that the page has changed. These are the delegate methods you listed in your question.
So, in your ViewController class you need to implement these delegate methods.
First, tell the compiler that your class implements the protocol:
class ViewController:UIViewController,CAPSPageMenuDelegate
Now, you need to set the view controller as the delegate. Where you create the CAPSPageMenu you will need something like this -
pageMenu.delegate=self
Finally, implement the delegate methods. The CAPSPageMenu is provided with an array of view controllers that it manages. You haven't given the precise details of these, but I am assuming that they implement some class which I am calling SubViewController. Define an integer property pageNumber in this class and then your delegate method can simply be -
func willMoveToPage(controller: UIViewController, index: Int) {
let subview=controller as! SubViewController
subview.pageNumber=index;
}
Then, in your SubViewController you can implement a setter on pageNumber that does whatever it needs to when the page number changes. In your delegate method you could also use the index to index into an array of strings (URLs say) and then set a string/URL property on the sub view controller - it depends on what you are trying to do.

Related

Table View Cells are not reaching to same array

I am trying to build an app which has object of Items and a controller for it which is called ItemsController. Also on my screen I suppose to have a table view and a button on it. The functionality of button is when it is clicked it needs to check favoriteItems array in ItemsController if it is found in that array remove element, if it isn't found there then append it to array. Operations for remove and append good but unfortunately all cells are not working together. They creates their own favoriteItems array.
To achieve this I tried to make ItemsController to be a singleton. I changed class to a struct and called ItemsController.sharedInstance everywhere. It actually solved a lot of my problem and I believe that the source I learnt this is not wrong about it. But why my tableview cells doesn't use ItemsController's favoriteItems array instead create theirs?
struct ItemsController {
var favoriteItems = [Items]()
static var sharedInstance = ItemsController()
init(){
itemsArray = [...items...]
}
}
class TableViewCell: UITableViewCell {
#IBOutlet weak var favoriteButton: UIButton!
let buttonFirstColor : UIColor = UIColor.clear
let buttonSecondColor : UIColor = UIColor(red: 224/255.0, green: 74/255.0, blue: 94/255.0, alpha: 1.0)
var itemsController = ItemsController.sharedInstance
var itemDedicated = Items(name: "", pic: "", aciklama: "")
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
favoriteButton.layer.cornerRadius = 0.5 * favoriteButton.bounds.size.width
favoriteButton.backgroundColor = UIColor.clear
favoriteButton.layer.borderColor = UIColor(red: 224/255.0, green: 74/255.0, blue: 94/255.0, alpha: 1.0).cgColor
favoriteButton.layer.borderWidth = 4.0
favoriteButton.clipsToBounds = true
setFavoriteButton()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#IBAction func favoriteButtonClicked(_ sender: Any) {
var favoriteFound = false
for items in itemsController.favoriteItems{
if(items.name == itemDedicated.name){
favoriteFound = true }
}
if(favoriteFound){
itemsController.favoriteItems.remove(at: itemsController.favoriteItems.index(of: itemDedicated)!)
} else {
itemsController.favoriteItems.append(itemDedicated)
}
setFavoriteButton()
}
private func setFavoriteButton(){
var favoriteFound = false
for items in itemsController.favoriteItems{
if(items.name == itemDedicated.name){
favoriteFound = true }
}
if(favoriteFound){
favoriteButton.backgroundColor = buttonSecondColor
favoriteButton.setTitleColor(buttonFirstColor, for: .normal)
} else {
favoriteButton.backgroundColor = buttonFirstColor
favoriteButton.setTitleColor(buttonFirstColor, for: .normal)
}
}
}

How to implement only one table controller for all segment in pager?

I am implementing custom horizontal multiple segments with table view controller as content of each segment. But how to implement only one controller for all segments, because view is same for all segments but only data is change.
I want to pass current index of segment to table view controller to get particular data.
I am using CAPSPageMenu.swift file from -https://codeload.github.com/uacaps/PageMenu/zip/master?
here is my code-
class Entrance_main_controller: UIViewController {
var pageMenu : CAPSPageMenu?
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// MARK: - UI Setup
self.title = "Entrance Exam"
// Initialize view controllers to display and place in array
var controllerArray : [UIViewController] = []
let controller1 : Entrance_Content_ViewController = Entrance_Content_ViewController(nibName: "TestTableViewController", bundle: nil)
controller1.title = "Engineering"
controllerArray.append(controller1)
let controller2 : Entrance_Content_ViewController = Entrance_Content_ViewController(nibName: "TestTableViewController", bundle: nil)
controller2.title = "Medical"
controllerArray.append(controller2)
let controller3 : Entrance_Content_ViewController = Entrance_Content_ViewController(nibName: "TestTableViewController", bundle: nil)
controller3.title = "Management"
controllerArray.append(controller3)
// Customize menu (Optional)
let parameters: [CAPSPageMenuOption] = [
.ScrollMenuBackgroundColor(UIColor(red: 30.0/255.0, green: 30.0/255.0, blue: 30.0/255.0, alpha: 1.0)),
.ViewBackgroundColor(UIColor(red: 20.0/255.0, green: 20.0/255.0, blue: 20.0/255.0, alpha: 1.0)),
.SelectionIndicatorColor(UIColor.orangeColor()),
.BottomMenuHairlineColor(UIColor(red: 70.0/255.0, green: 70.0/255.0, blue: 80.0/255.0, alpha: 1.0)),
.MenuItemFont(UIFont(name: "HelveticaNeue", size: 13.0)!),
.MenuHeight(40.0),
.MenuItemWidth(90.0),
.CenterMenuItems(true)
]
// Initialize scroll menu
pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRectMake(0.0, 0.0, self.view.frame.width, self.view.frame.height), pageMenuOptions: parameters)
self.addChildViewController(pageMenu!)
self.main_content_view.addSubview(pageMenu!.view)
pageMenu!.didMoveToParentViewController(self)
}
//here I am getting current index
func get_current_page() -> Int {
let currentIndex = pageMenu!.currentPageIndex
return currentIndex;
}
// MARK: - Container View Controller
override func shouldAutomaticallyForwardAppearanceMethods() -> Bool {
return true
}
override func shouldAutomaticallyForwardRotationMethods() -> Bool {
return true
}
}
here I am using Entrance_Content_ViewController class for all segments.In this controller I am calling get_current_page() method for current page index.
class Entrance_Content_ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
let entrance_main_controller = Entrance_main_controller()
let page = entrance_main_controller.get_current_page()
print("page no\(page)")
self.tableView.registerNib(UINib(nibName: "EntranceTableViewCell", bundle: nil), forCellReuseIdentifier: "EntranceTableViewCell")
}
But I am getting this error- fatal error: unexpectedly found nil while unwrapping an Optional value(lldb)
Please help me to solve this problem.
thank you
The basic idea you can implement is, maintain array of data for each segment. Then use switch over the segment index and as per segment index assign tableView DataSource.
The rough code should be like this:
switch(segmentIndex)
{
case: 0 yourDatasourceArray = segment0_DataArray
:
:
//like this for all segments.
}

Parameter for Action

I have Code Like this
func showSearchBar(searchBar: UISearchBar, navigationItem: UINavigationItem) {
searchBar.alpha = 0
navigationItem.titleView = searchBar
searchBar.showsCancelButton = true
navigationItem.setRightBarButtonItem(nil, animated: true)
for subView in searchBar.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
textField.attributedPlaceholder = NSAttributedString(string:NSLocalizedString("Search", comment:""),
attributes:[NSForegroundColorAttributeName: UIColor(red: 25/255, green: 128/255, blue: 214/255, alpha: 1)])
textField.font = UIFont(name:"AvenirNext-Medium", size: 15)
textField.textColor = UIColor(red: 65/255, green: 65/255, blue: 65/255, alpha: 1)
}
}
}
UIView.animateWithDuration(0.5, animations: {
searchBar.alpha = 1
}, completion: { finished in
searchBar.becomeFirstResponder()
})
}
func hideSearchBar(searchBar: UISearchBar, navigationItem: UINavigationItem, navigationController: UINavigationController, leftButton: UIBarButtonItem) {
let button = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: "showSearchBar:")
searchBar.alpha = 0
navigationController.navigationBar.topItem?.rightBarButtonItem = button
navigationItem.setLeftBarButtonItem(leftButton, animated: true)
searchBar.clipsToBounds = true
UIView.animateWithDuration(0.3, animations: {
navigationController.navigationBar.alpha = 1
}, completion: { finished in
})
}
I've error after func hideSearchBar called
I don't know but i think error because I call showSearchBar in hideSearchBar but on showSearchBar have 2 parameters but i not send it... how can I send 2 parameters on action
I have try
showSearchBar:
showSearchBar::
but it still error, what should i do?
or i have another error on my code?
To get the name right, you need to translate from a Swift method declaration to the Objective-C name of that method. This translation is simple and follows rules that are completely mechanical, but you will be entering the name as a literal string and it is all too easy to make a typing mistake, so be careful:
The name starts with everything that precedes the left parenthesis in the method name.
If the method takes no parameters, stop. That’s the end of the name.
If the method takes any parameters, add a colon.
If the method takes more than one parameter, add the external names of all parameters except the first parameter, with a colon after each external parameter name.
Observe that this means that if the method takes any parameters, its Objective-C name will end with a colon. Capitalization counts, and the name should contain no spaces or other punctuation except for the colons.
To illustrate, here are three Swift method declarations, with their Objective-C names given as a string in a comment:
func sayHello() -> String // "sayHello"
func say(s:String) // "say:"
func say(s:String, times n:Int) // "say:times:"
It is possible to crash even though your selector name corresponds correctly to a declared method. For example, here’s a small test class that creates an NSTimer and tells it to call a certain method once per second:
class MyClass {
var timer : NSTimer? = nil
func startTimer() {
self.timer = NSTimer.scheduledTimerWithTimeInterval(1,
target: self, selector: "timerFired:",
userInfo: nil, repeats: true)
}
func timerFired(t:NSTimer) {
println("timer fired")
}
}
There’s nothing wrong with that class structurally; it compiles, and can be instantiated when the app runs. But when we call startTimer, we crash. The problem is not that timerFired doesn’t exist, or that "timerFired:" is not its name; the problem is that Cocoa can’t find timerFired. This, in turn, is because our class MyClass is a pure Swift class; therefore it lacks the Objective-C introspection and message-sending machinery that would permit Cocoa to see and call timerFired. Any one of the following solutions will solve the problem:
Declare MyClass as a subclass of NSObject.
Declare MyClass with the #objc attribute.
Declare timerFired with the #obc attribute.
Declare timerFired with the dynamic keyword. (But this would be overkill; you should reserve use of dynamic for situations where it is needed, namely where Objective-C needs the ability to alter the implementation of a class member.)
Here is Documentation.
In your case do this way:
"showSearchBar:navigationItem:"
UPDATE:
Remove General.swift from your project and replace your code in Home.swift with this code:
#IBAction func searchBarAction(sender: AnyObject) {
showSearchBar(self.searchBar, navItem: self.navigationItem)
}
func showSearchBar(searchBar: UISearchBar, navItem navigationItem: UINavigationItem) {
searchBar.alpha = 0
navigationItem.titleView = searchBar
searchBar.showsCancelButton = true
navigationItem.setRightBarButtonItem(nil, animated: true)
for subView in searchBar.subviews {
for subsubView in subView.subviews {
if let textField = subsubView as? UITextField {
textField.attributedPlaceholder = NSAttributedString(string:NSLocalizedString("Search", comment:""),
attributes:[NSForegroundColorAttributeName: UIColor(red: 25/255, green: 128/255, blue: 214/255, alpha: 1)])
textField.font = UIFont(name:"AvenirNext-Medium", size: 15)
textField.textColor = UIColor(red: 65/255, green: 65/255, blue: 65/255, alpha: 1)
}
}
}
UIView.animateWithDuration(0.5, animations: {
searchBar.alpha = 1
}, completion: { finished in
searchBar.becomeFirstResponder()
})
}
//MARK: UISearchBarDelegate
func searchBarCancelButtonClicked(searchBar: UISearchBar) {
hideSearchBar(self.searchBar, navigationItem: self.navigationItem, navigationController: self.navigationController!, leftButton: btnMenu)
}
func hideSearchBar(searchBar: UISearchBar, navigationItem: UINavigationItem, navigationController: UINavigationController, leftButton: UIBarButtonItem) {
let button = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Search, target: self, action: "searchBarAction:") //add your button action here.
searchBar.alpha = 0
navigationItem.rightBarButtonItem = button
navigationItem.setLeftBarButtonItem(leftButton, animated: true)
searchBar.clipsToBounds = true
UIView.animateWithDuration(0.3, animations: {
navigationController.navigationBar.alpha = 1
}, completion: { finished in
})
}

Using Page View Controller inside Tab Swift

MY WORK SO FAR:
So I have a Tab bar that looks like this:
When I click on "Canteen" I want to be directed to a Page View Controller where I can swipe between different pages but stay on the same tab.
I have this somewhat working:
I have the Storyboard setup like this:
As you can see that segue above is coming from the Tab Bar Controller.
The third view (Can Page Item Controller, ID: "CanItemController) is used for all pages in the page view.
The second view above (Page View Controller, ID: "CanPageController) is used for controlling the Pages (duh)
The first view (CanteenViewController) contains all the code and makes all the connections. This is where everything goes on. The code inside this class is here:
import UIKit
class CanteenViewController: UIViewController, UIPageViewControllerDataSource {
// MARK: - Variables
private var pageViewController: UIPageViewController?
private let contentImages = ["Radar-512.png",
"dartp.png",
"roomp.png",
"abnews.png",
"canteenp.png"];
override func viewDidLoad() {
super.viewDidLoad()
createPageViewController()
setupPageControl()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func createPageViewController() {
let pageController = self.storyboard!.instantiateViewControllerWithIdentifier("CanPageController") as! UIPageViewController
pageController.dataSource = self
if contentImages.count > 0 {
let firstController = getItemController(0)!
let startingViewControllers: NSArray = [firstController]
pageController.setViewControllers(startingViewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
pageViewController = pageController
addChildViewController(pageViewController!)
self.view.addSubview(pageViewController!.view)
pageViewController!.didMoveToParentViewController(self)
}
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
appearance.backgroundColor = UIColor.darkGrayColor()
}
// MARK: - UIPageViewControllerDataSource
func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! CanPageItemController
if itemController.itemIndex > 0 {
return getItemController(itemController.itemIndex-1)
}
return nil
}
func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
let itemController = viewController as! CanPageItemController
if itemController.itemIndex+1 < contentImages.count {
return getItemController(itemController.itemIndex+1)
}
return nil
}
private func getItemController(itemIndex: Int) -> CanPageItemController? {
if itemIndex < contentImages.count {
let pageItemController = self.storyboard!.instantiateViewControllerWithIdentifier("CanItemController") as! CanPageItemController
pageItemController.itemIndex = itemIndex
pageItemController.imageName = contentImages[itemIndex]
return pageItemController
}
return nil
}
// MARK: - Page Indicator
func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
return contentImages.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
return 0
}
}
I HAVE 2 PROBLEMS:
I can't see any page indicators at all.
This comes from the following code:
private func setupPageControl() {
let appearance = UIPageControl.appearance()
appearance.pageIndicatorTintColor = UIColor.grayColor()
appearance.currentPageIndicatorTintColor = UIColor.whiteColor()
appearance.backgroundColor = UIColor.darkGrayColor()
}
Is there a way I can add a page indicator in the storyboard and reference that programatically. That way maybe I could add constraints and have more control. I think the page indicator might be hidden behind the Tab Bar. Though constraints are also giving me issues, which leads me to problem 2
As you can see in the Item Controller, I have a UIImageView and the constraints are all set right. But when I run the app the image appears for a second (completely out of proportion) and then disappears. i.e - my constraints simply don't work properly
Question
Is my approach in general just wrong? Or is there a few little changes I can make to fix the above problems. I I've been following a tutorial (on Ray Wenderlich I think), and it all worked fine until I tried to integrate it with my Tab Bar.
Leave all above thing, just do as following.
Edited : As per Swift 5
class CanteenViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet var scrHelp: UIScrollView!
#IBOutlet var pageControl: UIPageControl!
var page = 0
let arrContent: [[String: Any]] = [["name" : "Title1", "icon" : "Radar-512"],
["name" : "Title2", "icon" : "dartp"],
["name" : "Title3", "icon" : "roomp"],
["name" : "Title4", "icon" : "abnews"],
["name" : "Title5", "icon" : "canteenp"]]
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Canteen"
// Do any additional setup after loading the view, typically from a nib.
self.createHelpView()
self.pageControl.backgroundColor = UIColor.clear
self.pageControl.pageIndicatorTintColor = UIColor.lightGray
self.pageControl.currentPageIndicatorTintColor = UIColor(red: 251/255, green: 108/255, blue: 108/255, alpha: 1.0)
self.pageControl.tintAdjustmentMode = UIView.TintAdjustmentMode.dimmed
self.pageControl.numberOfPages = self.arrContent.count
self.pageControl.currentPage = 0
}
func createHelpView() {
var x = 50
var i = 0
for item in self.arrContent {
let lblTitle = UILabel(frame: CGRect(origin: CGPoint(x: CGFloat(x), y: 10), size: CGSize(width: CGFloat(self.scrHelp.frame.width-100), height: 25)))
lblTitle.autoresizingMask = UIView.AutoresizingMask.flexibleBottomMargin
lblTitle.backgroundColor = UIColor.clear
lblTitle.font = UIFont.systemFont(ofSize: 17)
lblTitle.textAlignment = NSTextAlignment.center
lblTitle.textColor = UIColor.black
lblTitle.text = item["name"] as? String //self.arrTitle[i]
self.scrHelp.addSubview(lblTitle)
let imgView = UIImageView(frame: CGRect(origin: CGPoint(x: CGFloat(x), y: 50), size: CGSize(width: CGFloat(self.scrHelp.frame.width-100), height: CGFloat(self.scrHelp.frame.height-150))))
imgView.autoresizingMask = UIView.AutoresizingMask.flexibleBottomMargin
imgView.backgroundColor = UIColor.clear
imgView.image = UIImage(named: (item["icon"] as! String))
imgView.contentMode = UIView.ContentMode.scaleAspectFit
self.scrHelp.addSubview(imgView)
x = x + Int(self.scrHelp.frame.width)
i = i + 1
}
self.scrHelp.contentSize = CGSize(width: (CGFloat(self.arrContent.count) * self.view.frame.width), height: 0)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageWidth = CGFloat(self.scrHelp.frame.width)
let fractionalPage = self.scrHelp.contentOffset.x / pageWidth
self.page = lround(CDouble(fractionalPage))
self.pageControl.currentPage = self.page
}
}
At last, add UIScrollView and UIPageControl to you storyboard and set respective outlet and constraint.

Swift and Xcode - How to Create Custom Tab Bar Icons

I have a tabbed application project I am working on in Xcode written in Swift (Xcode 6.3 and Swift 1.2). I am having a lot of trouble with custom Tab Bar icons. I have designed an image in Photoshop (CS6), saved it as a PNG, resized it in Prepo to be 30x30 and imported it into Xcode in the asset library. I then set the tab view controllers icon to that image. However, it doesn't show up.
I have looked at these pages but not found any help:
https://www.youtube.com/watch?v=4qqqoAWNfZA
Custom tab bar icon colors
http://www.raywenderlich.com/forums/viewtopic.php?f=2&t=19333
http://www.appcoda.com/ios-programming-how-to-customize-tab-bar-background-appearance/
https://www.youtube.com/watch?v=4Tj_SeApUrs
What is the proper process to create custom tab bar icons?
After a bit of research I resolved the issue, so thought I'd post here in case anyone else has a similar issue. In Photoshop I did the following:
Imported the image I wanted to use as the tab bar icon (its easier if you use a black and white image so that you don't have to remove colour).
Set the background to 'Transparent' rather than white.
Removed all white from the image so that it was just a black image with a transparent background.
Saved the image as a .png.
Resized the image to be a square with dimensions 75x75 pixels (and named imageName#3x.png), 50x50 pixels (and named imageName#2x.png), and 25x25 pixels (and named imageName.png)
In Xcode I did the following:
Dragged the images into Xcode and renamed the image group as icoImageName.
Selected the tab I wanted to set the image for in the storyboard in Xcode and set the 'Image' (under 'Bar Item' in the Inspector Pane) to icoImageName. Note that I did not set the 'Selected Image' under the 'Tab Bar Item' (leave this blank).
Done.
I hope this helps someone. Thanks to everyone for their help as well.
It sounds like you have everything set up properly in xCode. The problem IS the png file you are using.
Download this image, http://i.stack.imgur.com/zluev.png , and see if the problem persists.
According to an answer on UITabBarItem images just appear as a grey block:
The standard tabbar icons in iOS are rendered solely from the alpha channel. Colors are ignored completely. Instead of colors you can use different alpha values that lead to a different shade of gray (or blue if selected)
Make the background of your icons transparent.
Did you create the tab view in interface builder? If so, since you added the images as an asset they should show up in the 'Image' property of each tab button under the inspector sidebar. Also, I know you've already posted a ton of tutorials, but this one is pretty up to date and explains it thoroughly: http://codewithchris.com/ios-tab-bar-app/
class ViewController: UIViewController {
#IBOutlet var btnHome : UIButton!
#IBOutlet var btnInvoice : UIButton!
#IBOutlet var btnSettings : UIButton!
#IBOutlet var btnMyOrder : UIButton!
#IBOutlet var btnLogout : UIButton!
#IBOutlet weak var viewContainer: UIView!
var navController : UINavigationController!
var selectedIndex : Int! = 0
var arrTabColor = [UIColor(red: 35.0/255.0, green: 93.0/255.0, blue: 175.0/255.0, alpha: 1.0),
UIColor(red: 29.0/255.0, green: 86.0/255.0, blue: 167.0/255.0, alpha: 1.0),
UIColor(red: 35.0/255.0, green: 93.0/255.0, blue: 175.0/255.0, alpha: 1.0),
UIColor(red: 29.0/255.0, green: 86.0/255.0, blue: 167.0/255.0, alpha: 1.0),
UIColor(red: 35.0/255.0, green: 93.0/255.0, blue: 175.0/255.0, alpha: 1.0)]
var arrTabIdentiFierVC = ["FirstVC","SecondVC","FirstVC","FirstVC","SecondVC"]
// MARK: - Life Cycle
override func viewDidLoad()
{
super.viewDidLoad()
setTabbarImage(0)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setTabBarClicked(_ storyIdentifier : String,identifier : String)
{
let aStoryboard = UIStoryboard.init(name: storyIdentifier, bundle: nil)
let newViewController = aStoryboard.instantiateViewController(withIdentifier: identifier)
navController = UINavigationController(rootViewController: newViewController)
self.addChildViewController(navController)
navController.view.frame = viewContainer.frame
newViewController.view.frame = viewContainer.frame
self.viewContainer.addSubview(navController.view)
newViewController.didMove(toParentViewController: self)
}
func setTabbarImage(_ selectedIndex : Int!)
{
btnHome.backgroundColor = arrTabColor[0]
btnInvoice.backgroundColor = arrTabColor[1]
btnSettings.backgroundColor = arrTabColor[2]
btnMyOrder.backgroundColor = arrTabColor[3]
btnLogout.backgroundColor = arrTabColor[4]
let selectedColor = UIColor(red: 40/255, green: 142/255, blue: 206.0/255, alpha: 1.0)
if selectedIndex == 0
{
btnHome.backgroundColor = selectedColor
}
else if selectedIndex == 1
{
btnInvoice.backgroundColor = selectedColor
}
else if selectedIndex == 2
{
btnSettings.backgroundColor = selectedColor
}
else if selectedIndex == 3
{
btnMyOrder.backgroundColor = selectedColor
}
else if selectedIndex == 4
{
btnLogout.backgroundColor = selectedColor
}
}
// MARK: - Action Method
#IBAction func HomeClicked(_ sender : AnyObject?)
{
setTabbarImage(0)
setTabBarClicked("Main",identifier: arrTabIdentiFierVC[0])
}
#IBAction func InvoiceClicked(_ sender : AnyObject?)
{
setTabbarImage(1)
setTabBarClicked("Main",identifier: arrTabIdentiFierVC[1])
}
#IBAction func SettingClicked(_ sender : AnyObject?)
{
setTabbarImage(2)
setTabBarClicked("Main",identifier: arrTabIdentiFierVC[2])
}
#IBAction func MyorderClicked(_ sender : AnyObject?)
{
setTabbarImage(3)
setTabBarClicked("Main",identifier: arrTabIdentiFierVC[3])
}
#IBAction func logoutClicked(_ sender : AnyObject?)
{
setTabbarImage(4)
let alert = UIAlertController(title: "", message: "Are you sure want to logout?", preferredStyle: UIAlertControllerStyle.alert)
let CancelAction = UIAlertAction(title: "NO", style: .default) { (action:UIAlertAction!) in
}
alert.addAction(CancelAction)
let OKAction = UIAlertAction(title: "YES", style: .default) { (action:UIAlertAction!) in
// var isNav : Bool! = false
//for objChild in (self.parent?.childViewControllers)!
// {
// if objChild.isKind(of: LoginVC.self)
// {
// self.navigationController!.popToViewController(objChild, animated: true)
// CommonMethods.removeCustomObject(Constants.kUserProfile)
//
// isNav = true
// break
//
// }
// }
// if !isNav
// {
// CommonMethods.removeCustomObject(Constants.kUserProfile)
// let aNavController = (AppDelegate.getDelegate().window!.rootViewController! as! UINavigationController)
// let storyboard = UIStoryboard(name: "Main", bundle: nil)
// var aVCObj = UIViewController()
// aVCObj = storyboard.instantiateViewController(withIdentifier: "LoginVC")
// var aMutArr = aNavController.viewControllers
// aMutArr.insert(aVCObj, at: 0)
// aNavController.viewControllers = aMutArr
// aNavController.popToRootViewController(animated: true)
// }
}
alert.addAction(OKAction)
self.present(alert, animated: true, completion: nil)
}
// MARK: - Action Method
}

Resources