i am using sambag time picker controller and i am set time on button on method of sambag picker but issue is that i have multiple buttons in one view controller so i did this for every but on set time method at the time of set button all buttons title are change what i want is that only change value of button which i pressed
here i will show you what i tried i will show you with my code
import UIKit
class ManageHoursViewController: UIViewController {
var theme: SambagTheme = .light
var result : String!
#IBOutlet weak var btnMonStartTime: UIButton!
#IBOutlet weak var btnMonEndTime: UIButton!
#IBOutlet weak var btnMonOff: UIButton!
#IBOutlet weak var btnMonOn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
round()
let hh2 = (Calendar.current.component(.hour, from: Date()))
let mm2 = (Calendar.current.component(.minute, from: Date()))
print(hh2)
print(mm2)
let dateTime = "\(hh2) : \(mm2)"
btnMonStartTime.setTitle("\(dateTime)", for: .normal)
btnMonEndTime.setTitle("\(dateTime)", for: .normal)
// Do any additional setup after loading the view.
}
func round(){
btnMonOff.isHidden = true
btnMonStartTime.layer.cornerRadius = btnMonStartTime.frame.height / 2
btnMonStartTime.layer.shadowColor = UIColor(red: 154/255, green: 154/255, blue: 154/255, alpha: 1).cgColor
btnMonStartTime.layer.shadowOffset = CGSize(width: 0, height: 1)
btnMonStartTime.layer.shadowOpacity = 1.0
btnMonStartTime.layer.shadowRadius = 2.0
btnMonStartTime.layer.masksToBounds = false
btnMonEndTime.layer.cornerRadius = btnMonEndTime.frame.height / 2
btnMonEndTime.layer.shadowColor = UIColor(red: 154/255, green: 154/255, blue: 154/255, alpha: 1).cgColor
btnMonEndTime.layer.shadowOffset = CGSize(width: 0, height: 1)
btnMonEndTime.layer.shadowOpacity = 1.0
btnMonEndTime.layer.shadowRadius = 2.0
btnMonEndTime.layer.masksToBounds = false
}
#IBAction func btnMonStartTimeTapped(_ sender: UIButton) {
let vc = SambagTimePickerViewController()
vc.theme = theme
vc.delegate = self
present(vc, animated: true, completion: nil)
}
#IBAction func btnMonEndTimeTapped(_ sender: UIButton) {
let vc = SambagTimePickerViewController()
vc.theme = theme
vc.delegate = self
present(vc, animated: true, completion: nil)
}
}
extension ManageHoursViewController : SambagTimePickerViewControllerDelegate {
func sambagTimePickerDidSet(_ viewController: SambagTimePickerViewController, result: SambagTimePickerResult) {
self.result = "\(result)"
print(self.result)
btnMonStartTime.setTitle(self.result, for: .normal)
btnMonEndTime.setTitle(self.result, for: .normal)
viewController.dismiss(animated: true, completion: nil)
}
func sambagTimePickerDidCancel(_ viewController: SambagTimePickerViewController) {
viewController.dismiss(animated: true, completion: nil)
}
}
i want like when monday start time button press then and i select time form picker then only monday start time button value change at now all button value changed
You can create a var to track last clicked one
var lastBu: UIButton!
#IBAction func btnMonStartTimeTapped(_ sender: UIButton) {
let vc = SambagTimePickerViewController()
vc.theme = theme
vc.delegate = self
lastBu = sender
present(vc, animated: true, completion: nil)
}
#IBAction func btnMonEndTimeTapped(_ sender: UIButton) {
let vc = SambagTimePickerViewController()
vc.theme = theme
vc.delegate = self
lastBu = sender
present(vc, animated: true, completion: nil)
}
Related
I have one UIViewController that I am trying to send the titleLabel of a UIButton to a UILabel held within a different UIView Controller.
I have followed the same steps and pattern as within a previous method that worked fine, but the Title Text is just not getting passed onto the next VC.
I have a Button class called MtsCardsButton, but this just sets the animation and appearance of the button.
Thank you for reviewing.
Here is my code for the Button in the first VC:
import UIKit
class MTSCardsPage: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//This is to make mtsCardsSetArray available to this ViewController
let otherVC = MTSDiscriminators()
mtsCardsSetArray2 = otherVC.mtsCardsSetArray
let otherVC2 = MTSDiscriminators()
allMtsDescriminatorsArray2 = otherVC2.allMtsDescriminatorsArray
//Set Card Titles from Array
Card1ButtonOutlet.setTitle(mtsCardsSetArray2[0], for: .normal)
Card2ButtonOutlet.setTitle(mtsCardsSetArray2[1], for: .normal)
Card3ButtonOutlet.setTitle(mtsCardsSetArray2[2], for: .normal)
Card4ButtonOutlet.setTitle(mtsCardsSetArray2[3], for: .normal)
Card5ButtonOutlet.setTitle(mtsCardsSetArray2[4], for: .normal)
//Do any additional setup after loading the view.
}
var mtsCardsButton = MtsCardsButton()
func addActionToMtsCardsButton() {
mtsCardsButton.addTarget(self, action: #selector(CardButton), for: .touchUpInside)
}
//This is to TELL the Button to do something AND to goto
//the MTS Discriminators UIView.
var cardButtonPressed = ""
#IBAction func CardButton(_ sender: MtsCardsButton) {
let secondVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "DiscrimUIViewCollection") as! DiscrimUIViewCollection
cardButtonPressed = sender.currentTitle!
secondVC.updateTheLabel2 = cardButtonPressed
////I'VE TRIED THIS SECTION INSTEAD OF ABOVE AND IT STILL DOESN'T WORK.
// func prepare(for segue: UIStoryboardSegue, sender: Any?)
// {
// if segue.destination is DiscrimUIViewCollection
// {
// let vc = segue.destination as? DiscrimUIViewCollection
// vc?.updateTheLabel2 = cardButtonPressed
// }
// }
//switch area to make button move when pressed
switch cardButtonPressed {
case mtsCardsSetArray2[0]:
Card1ButtonOutlet.shakeMtsCardsButton()
case mtsCardsSetArray2[1]:
Card2ButtonOutlet.shakeMtsCardsButton()
case mtsCardsSetArray2[2]:
Card3ButtonOutlet.shakeMtsCardsButton()
case mtsCardsSetArray2[3]:
Card4ButtonOutlet.shakeMtsCardsButton()
case mtsCardsSetArray2[4]:
Card5ButtonOutlet.shakeMtsCardsButton()
default:
print("Error, unrecognised button pressed!")
}
guard let destinationVC = storyboard?.instantiateViewController(withIdentifier: "DiscrimUIViewCollection") as? DiscrimUIViewCollection else {
return
}
present(destinationVC, animated: true, completion: nil)
}
//Outlet for sending anything to the MTS Card Button
#IBOutlet weak var Card1ButtonOutlet: MtsCardsButton!
#IBOutlet weak var Card2ButtonOutlet: MtsCardsButton!
#IBOutlet weak var Card3ButtonOutlet: MtsCardsButton!
#IBOutlet weak var Card4ButtonOutlet: MtsCardsButton!
#IBOutlet weak var Card5ButtonOutlet: MtsCardsButton!
}
Here is the code for the second receiving VC:
class DiscrimUIViewCollection: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
#IBOutlet weak var discriminatorTitle: UILabel!
var updateTheLabel2: String?
#IBAction func discrimButtonPressed(_ sender: UIButton) {
//action here to name what discriminator means.
print(sender.currentTitle!)
}
#IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
Card1ButtonOutlet.setTitle(mtsCardsSetArray2[0], for: .normal)
Card2ButtonOutlet.setTitle(mtsCardsSetArray2[1], for: .normal)
Card3ButtonOutlet.setTitle(mtsCardsSetArray2[2], for: .normal)
Card4ButtonOutlet.setTitle(mtsCardsSetArray2[3], for: .normal)
Card5ButtonOutlet.setTitle(mtsCardsSetArray2[4], for: .normal)
collectionView.dataSource = self
collectionView.delegate = self
self.collectionView.backgroundColor = .black
discriminatorTitle.text = updateTheLabel2
discriminatorTitle.font = UIFont(name: "Mukta Mahee", size: 18)
discriminatorTitle.font = UIFont.boldSystemFont(ofSize: 18)
discriminatorTitle.numberOfLines = 2
discriminatorTitle.minimumScaleFactor = 0.1
discriminatorTitle.baselineAdjustment = .alignCenters
discriminatorTitle.textAlignment = NSTextAlignment.center
discriminatorTitle.clipsToBounds = true
discriminatorTitle.backgroundColor = colourYellow
discriminatorTitle.textColor = .black
discriminatorTitle.layer.borderColor = UIColor.black.cgColor
discriminatorTitle.layer.borderWidth = 2.0
discriminatorTitle.layer.cornerRadius = 7
discriminatorTitle.layer.shadowColor = UIColor.black.cgColor
discriminatorTitle.layer.shadowOffset = CGSize(width: 0.0, height: 6.0)
discriminatorTitle.layer.shadowRadius = 7
discriminatorTitle.layer.shadowOpacity = 0.5
discriminatorTitle.clipsToBounds = false
discriminatorTitle.layer.masksToBounds = true
let layout = self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
layout.minimumInteritemSpacing = 2
layout.itemSize = CGSize(width: (self.collectionView.frame.size.width - 0)/1, height:self.collectionView.frame.size.height/3)
//Do any additional setup after loading the view.
func numberOfSections(in collectionView: UICollectionView) -> Int {
// 1
return 1
}
}
So, after many hours of studying up various websites I found the answer. I needed to add code and re-position the code. I Changed the Storyboard ID to match the DiscrimUIViewCollection.swift file.
I place the following code at the bottom of the 'switch' statement in the MTSCardsPage.swift file.
//To capture the card title and store it for
//preparation for changing based on Label.
guard let DiscrimUIViewCollection : DiscrimUIViewCollection = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DiscrimUIViewCollection") as? DiscrimUIViewCollection else {
return
}
DiscrimUIViewCollection.updateTheLabel = sender.currentTitle!
present(DiscrimUIViewCollection, animated: true, completion: nil)
}
And to my delight, it all works fine!
The website I used to help me the most was this one:
https://fluffy.es/3-ways-to-pass-data-between-view-controllers/
Thanks for your assistance guys, each little comment made me think.
It's big learning curve!
I'm a beginner in IOS. I'm developping a Swift app and I am using a UISegmentedControl. It displays well in ios 11, but when I run my app on a IOS 10 device, the segmented control is not showing. Does anyone know why ?
Is the segmented control only available in IOS 11 ?
Here are the screenshots of my app (sorry I can't post images yet) :
IOS 11
IOS10
Here is my SegmentedViewController.swift :
import UIKit
import MMDrawerController
class SegmentedViewController: UIViewController {
#IBOutlet weak var viewContainer: UIView!
var segmentedController: UISegmentedControl!
var floorRequest:Int = 0
var segmentedControlIndex:Int = 0
lazy var travelViewController: TravelViewController = {
var viewController = self.initTravelViewController()
return viewController
}()
lazy var nearbyViewController: NearbyTableViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
var viewController = storyboard.instantiateViewController(withIdentifier: "NearbyTableViewController") as! NearbyTableViewController
self.addViewControllerAsChildViewController(childViewController: viewController)
return viewController
}()
var views: [UIView]!
let appDelegate:AppDelegate = UIApplication.shared.delegate as! AppDelegate
func initTravelViewController() -> TravelViewController {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let viewController = storyboard.instantiateViewController(withIdentifier: "TravelViewController") as! TravelViewController
viewController.floorRequest = floorRequest
self.addViewControllerAsChildViewController(childViewController: viewController)
return viewController
}
override func viewDidLoad() {
super.viewDidLoad()
segmentedController = UISegmentedControl()
navigationItem.titleView = segmentedController
self.title = "TAB_BAR_MAP".localized()
}
override func viewWillAppear(_ animated: Bool) {
self.tabBarController?.navigationItem.title = "MENU_SECTION_TRAVEL".localized().uppercased()
// Navigation Bar
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white, NSFontAttributeName: UIFont(name: "Lato-Bold", size: 18)!]
self.navigationController?.navigationBar.tintColor = .white
self.navigationController?.navigationBar.barTintColor = appDelegate.colorAqaDark
self.navigationController?.navigationBar.isTranslucent = false
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
if (self.navigationController?.viewControllers.count)! < 2 {
let buttonLeft: UIButton = appDelegate.aqaBarButton(image: #imageLiteral(resourceName: "IconWhiteMenu"))
buttonLeft.addTarget(self, action: #selector(toggleMenu), for: .touchUpInside)
buttonLeft.frame = CGRect.init(x: 0, y: 0, width: 25, height: 25)
let buttonMenu = UIBarButtonItem(customView: buttonLeft)
self.navigationItem.setLeftBarButton(buttonMenu, animated: false);
}
setupView()
super.viewWillAppear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func toggleMenu() {
appDelegate.mainContainer!.toggle(MMDrawerSide.left, animated: true, completion: nil)
}
private func setupView(){
setupSegmentedControl()
updateView()
}
private func updateView(){
travelViewController.view.isHidden = !(segmentedController.selectedSegmentIndex == 0)
nearbyViewController.view.isHidden = (segmentedController.selectedSegmentIndex == 0)
segmentedControlIndex = segmentedController.selectedSegmentIndex
}
private func setupSegmentedControl(){
segmentedController.removeAllSegments()
segmentedController.insertSegment(withTitle: "TAB_BAR_MAP".localized(), at: 0, animated: false)
segmentedController.insertSegment(withTitle: "TAB_BAR_NEARBY".localized(), at: 1, animated: false)
segmentedController.addTarget(self, action: #selector(selectionDidChange(sender:)), for: .valueChanged)
segmentedController.selectedSegmentIndex = segmentedControlIndex
}
func selectionDidChange(sender: UISegmentedControl){
updateView()
}
private func addViewControllerAsChildViewController(childViewController: UIViewController){
addChildViewController(childViewController)
view.addSubview(childViewController.view)
childViewController.view.frame = view.bounds
childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
childViewController.didMove(toParentViewController: self)
}
}
The problem is that you are not giving the segmented control any size. In iOS 11 the title view is sized internally by autolayout, but not in iOS 10 or before. So you end up with a segmented control of zero size.
When i tapped on my TabBar's first image it should be highlighted like the below image -
enter image description here
But when i tap on the first icon it's doing nothing, tap on the second icon it's highlighting the first icon, tap on the 3rd icon highlighting it's previous icon (second icon) and so on. It might be an indexing problem. Need some help to find this issue. Thank you. My TabBar current view-
enter image description here
Here is my code -
import UIKit
class ViewController: BaseViewController {
//MARK: Outlets
#IBOutlet var warningsIcon: UIImageView!
#IBOutlet var incidentsIcon: UIImageView!
#IBOutlet var notificationsIcon: UIImageView!
#IBOutlet var myMessagesIcon: UIImageView!
#IBOutlet var warningsTitle: UILabel!
#IBOutlet var incidentsTitle: UILabel!
#IBOutlet var notificationsTitle: UILabel!
#IBOutlet var myMessagesTitle: UILabel!
#IBOutlet var containerView: UIView!
//MARK: PROPERTIES
var previousSelectedIcon:UIImageView!
var previousSeelctedTitle:UILabel!
var previousIndex:Int!
var currentIndex:Int!
var previousVc:UIViewController!
fileprivate var i = 0
open var subViewController:UIViewController?
var unTappedIcon = ["warnings","incidents","notifications","my-messages"]
var tappedIcon = ["warnings_tapped","Incidents_tapped","notifications_tapped","myMessages_tapped"]
override func viewDidLoad() {
super.viewDidLoad()
addSlideMenuButton()
// Do any additional setup after loading the view, typically from a nib.
previousVc = self;
previousSelectedIcon = warningsIcon
previousSeelctedTitle = warningsTitle
previousIndex = 0;
currentIndex = 0;
//place sub view controller if any
placeSubViewControllerIfNeeded()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//place sub view controller if needed
func placeSubViewControllerIfNeeded() -> Void{
if let vc = subViewController {
vc.view.frame = self.containerView.frame
self.addChildViewController(vc)
//vc.view.frame = self.view.frame
self.containerView.addSubview(vc.view)
self.view.sendSubview(toBack: vc.view)
}
}
//MARK: For Tab bar
func updateTapView(title:UILabel, icon:UIImageView) {
previousSeelctedTitle.textColor = UIColor(red:0.60, green:0.60, blue:0.60, alpha:1.0)
previousSelectedIcon.image = UIImage.init(named: unTappedIcon[previousIndex])
title.textColor = UIColor(red:0.26, green:0.18, blue:0.49, alpha:1.0)
icon.image = UIImage.init(named: tappedIcon[currentIndex])
}
func removePreviousViewController() {
previousVc.willMove(toParentViewController: nil)
previousVc.view.removeFromSuperview()
previousVc.removeFromParentViewController()
}
func getStoryBoardByIndentifier(identifier:String)->UIStoryboard {
return UIStoryboard.init(name: identifier, bundle: nil)
}
func showSubViewContrller(subViewController:UIViewController) {
self.addChildViewController(subViewController)
subViewController.view.frame = containerView.frame
self.containerView.addSubview(subViewController.view)
subViewController.didMove(toParentViewController: self)
previousVc = subViewController
}
//Mark:- Action button for warnings
#IBAction func onClickWarnings(_ sender: UITapGestureRecognizer) {
print("Hi there i am just a warning")
self.warningsIcon.image = UIImage.init(named: "warnings_tapped")
previousIndex = currentIndex
currentIndex = 0
updateTapView( title: warningsTitle, icon: warningsIcon)
previousSeelctedTitle = warningsTitle
previousSelectedIcon = warningsIcon
if i > 0{
removePreviousViewController()
print("i am already removed")
}
let storyBoard = getStoryBoardByIndentifier(identifier: "warnings")
let vc = storyBoard.instantiateViewController(withIdentifier: "WarningsViewController") as! WarningsViewController
showSubViewContrller(subViewController: vc)
i += 1
}
//Mark:- Action button for warnings
#IBAction func onClickIncidents(_ sender: UITapGestureRecognizer) {
print("Hi there i am just a warning")
self.incidentsIcon.image = UIImage.init(named: "Incidents_tapped")
previousIndex = currentIndex
currentIndex = 1
updateTapView( title: incidentsTitle, icon: incidentsIcon)
previousSeelctedTitle = incidentsTitle
previousSelectedIcon = incidentsIcon
if i > 0{
removePreviousViewController()
print("i am already removed")
}
let storyBoard = getStoryBoardByIndentifier(identifier: "incidents")
let vc = storyBoard.instantiateViewController(withIdentifier: "IncidentsViewController") as! IncidentsViewController
showSubViewContrller(subViewController: vc)
i += 1
}
//Mark:- Action button for warnings
#IBAction func onClickNotifications(_ sender: UITapGestureRecognizer) {
print("Really true")
self.notificationsIcon.image = UIImage.init(named: "notifications_tapped")
previousIndex = currentIndex
currentIndex = 2
updateTapView(title: notificationsTitle, icon: notificationsIcon)
previousSeelctedTitle = notificationsTitle
previousSelectedIcon = notificationsIcon
if i > 0 {
removePreviousViewController()
print("I am already removed")
}
let storyBoard = getStoryBoardByIndentifier(identifier: "notifications")
let vc = storyBoard.instantiateViewController(withIdentifier: "NotificationsViewController") as! NotificationsViewController
showSubViewContrller(subViewController: vc)
i += 1
}
//Mark:- Action button for warnings
#IBAction func onClickMyMessages(_ sender: UITapGestureRecognizer) {
print("ha ha..i believe in that")
self.myMessagesIcon.image = UIImage.init(named: "myMessages_tapped")
previousIndex = currentIndex
currentIndex = 3
updateTapView(title: myMessagesTitle , icon: myMessagesIcon)
previousSeelctedTitle = myMessagesTitle
previousSelectedIcon = myMessagesIcon
if i > 0 {
removePreviousViewController()
print("i am alreday removed")
}
let storyBoard = getStoryBoardByIndentifier(identifier: "myMessages")
let vc = storyBoard.instantiateViewController(withIdentifier: "MyMessagesViewController") as! MyMessagesViewController
showSubViewContrller(subViewController: vc)
i += 1
}
}
Looks like you are adding view ineach viewcotroller which you want to show as if a tab bar item.. this might not be the right way to do.. what you can do is make your custom tabbar controller
class SampleViewController: UITabBarController {
#IBOutlet var tabBarView: UIView!
#IBOutlet weak var item1Btn: UIButton!
#IBOutlet weak var item2Btn: UIButton!
#IBOutlet weak var item3Btn: UIButton!
#IBOutlet weak var item4Btn: UIButton!
#IBOutlet weak var item5Btn: UIButton!
let item1Image = #imageLiteral(resourceName: "profileUnselected")
let item1Selected = #imageLiteral(resourceName: "profile")
let item2Image = #imageLiteral(resourceName: "notificationUnselected")
let item2Selected = #imageLiteral(resourceName: "notificationSelected")
let item3Image = #imageLiteral(resourceName: "game")
let item3Selected = #imageLiteral(resourceName: "game")
let item4Image = #imageLiteral(resourceName: "cookbooksUnselected")
let item4Selected = #imageLiteral(resourceName: "cookbooks")
let item5Image = #imageLiteral(resourceName: "searchTabUnselected")
let item5Selected = #imageLiteral(resourceName: "searchTabSelected")
let unSelectedColor = UIColor.lightGray
let selectedColor = UIColor.white
let appColor = UIColor(red: 22.0/255.0, green: 168.0/255.0, blue: 225.0/255.0, alpha: 1.0)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if UIDevice().userInterfaceIdiom == .phone {
switch UIScreen.main.nativeBounds.height {
case 2436:
offsetHeight = 44.0
default:
print("unknown")
}
}
addTabView()
}
func addTabView() {
Bundle.main.loadNibNamed("TabBarView", owner: self, options: nil)
tabBarView.frame = CGRect(x:
0 , y: Helper.getScreenHeight() - AppConstants.kTabBarheight - offsetHeight, width: Helper.getScreenWidth(), height: AppConstants.kTabBarheight)
self.view.addSubview(tabBarView)
self.item3Btn.sendActions(for: .touchUpInside) //here i showed my third tab bar item initially
}
#IBAction func tabBarBtnClick(_ sender: UIButton) {
var isViewToChange = false
let currentIndex = self.selectedIndex
var tochangeIndex = sender.tag
self.item1Btn.setImage(item1Image, for: .normal)
self.item2Btn.setImage(item2Image, for: .normal)
self.item3Btn.setImage(item3Image, for: .normal)
self.item4Btn.setImage(item4Image, for: .normal)
self.item5Btn.setImage(item5Image, for: .normal)
switch sender.tag {
case 0:
self.item1Btn.setImage(item1Selected, for: .normal)
if currentIndex != 0{
isViewToChange = true
tochangeIndex = 0
}
else{
(self.viewControllers?[currentIndex] as! UINavigationController).popToRootViewController(animated: true)
}
case 1:
self.item2Btn.setImage(item2Selected, for: .normal)
if currentIndex != 1{
isViewToChange = true
tochangeIndex = 1
}
else{
(self.viewControllers?[currentIndex] as! UINavigationController).popToRootViewController(animated: true)
}
case 2:
if currentIndex != 2{
isViewToChange = true
tochangeIndex = 2
}
else{
(self.viewControllers?[currentIndex] as! UINavigationController).popToRootViewController(animated: true)
}
case 3:
self.item4Btn.setImage(item4Selected, for: .normal)
if currentIndex != 3{
isViewToChange = true
tochangeIndex = 3
}
else{
(self.viewControllers?[currentIndex] as! UINavigationController).popToRootViewController(animated: true)
}
case 4:
self.item5Btn.setImage(item5Selected, for: .normal)
if currentIndex != 4{
isViewToChange = true
tochangeIndex = 4
}
else{
(self.viewControllers?[currentIndex] as! UINavigationController).popToRootViewController(animated: true)
}
default:
break
}
if isViewToChange {
let _ = self.selectedViewController?.view
let _ = self.viewControllers?[tochangeIndex].view
self.selectedIndex = tochangeIndex
}
}
func hideTabbar() {
self.tabBar.isHidden = true
var frame = tabBarView.frame
frame.origin.y = Helper.getScreenHeight() + 200
tabBarView.frame = frame
}
func showTabbar() {
self.tabBar.isHidden = false
var frame = tabBarView.frame
frame.origin.y = Helper.getScreenHeight() - AppConstants.kTabBarheight - offsetHeight
tabBarView.frame = frame
}
}
here i have aded methods for you to either show the tab bar of hide as we push into the stack of each tab bar item..
Here added few images for your understanding
and also dont forgot to set the tag for each button in tab bar view, so that when any button clicked, same method is called and we handle it from there
I'm making an app that uses Google Maps/Places API and I'm using the GMSAutocomplete View Controller. Once the user chooses a location, I show that location's restaurants on both a map and a table view, but I get the error mentioned above in the title and I'm not sure why.
The error happens at this instruction:
mapViewController.mapView.camera = camera
// OUTLETS
#IBOutlet weak var mapButton: UIButton!
#IBOutlet weak var listButton: UIButton!
#IBOutlet weak var container: UIView!
#IBOutlet var toggle : [UIButton]!
// VARIABLES
var listViewController = exploreListViewController!
var mapViewController = exploreMapsViewController!
var viewControllers : [UIViewController]!
var selectedIndex : Int = 0
var listVC = exploreListViewController()
override func viewDidLoad() {
super.viewDidLoad()
listButton.roundCorners([.topLeft,.bottomLeft], radius: 5, borderColor: nil, borderWidth: nil)
mapButton.roundCorners([.topRight,.bottomRight], radius: 5, borderColor: UIColor.white, borderWidth: 5)
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
listViewController = storyBoard.instantiateViewController(withIdentifier: "list") as! exploreListViewController
mapViewController = storyBoard.instantiateViewController(withIdentifier: "maps") as! exploreMapsViewController
viewControllers = [listViewController, mapViewController]
toggle[selectedIndex].isSelected = true
toggleViews(toggle[selectedIndex])
}
#IBAction func toggleViews(_ sender: UIButton) {
// REMOVING PREVIOUS VIEW CONTROLLER
let previousIndex = selectedIndex
let previousVC = viewControllers[previousIndex]
selectedIndex = sender.tag
toggle[previousIndex].isSelected = false
previousVC.willMove(toParentViewController: nil)
previousVC.view.removeFromSuperview()
previousVC.removeFromParentViewController()
// ADDING SELECTED VIEW CONTROLLER
sender.isSelected = true
let currentVC = viewControllers[selectedIndex]
addChildViewController(currentVC)
currentVC.view.frame = container.bounds
container.addSubview(currentVC.view)
currentVC.didMove(toParentViewController: self)
}
#IBAction func switchToList(_ sender: UIButton) {
listButton.setTitleColor(UIColor.red, for: .normal)
listButton.backgroundColor = UIColor.white
listButton.roundCorners([.bottomLeft,.topLeft], radius: 5, borderColor: nil, borderWidth: nil)
mapButton.setTitleColor(UIColor.white, for: .normal)
mapButton.backgroundColor = UIColor.red
mapButton.roundCorners([.bottomRight,.topRight], radius: 5, borderColor: UIColor.white, borderWidth: 5)
}
#IBAction func switchToMap(_ sender: UIButton) {
mapButton.setTitleColor(UIColor.red, for: .normal)
mapButton.backgroundColor = UIColor.white
mapButton.roundCorners([.bottomRight,.topRight], radius: 5, borderColor: nil, borderWidth: nil)
listButton.setTitleColor(UIColor.white, for: .normal)
listButton.backgroundColor = UIColor.red
listButton.roundCorners([.bottomLeft,.topLeft], radius: 5, borderColor: UIColor.white, borderWidth: 5)
}
// MARK: GOOGLE AUTOCOMPLETE DELEGATE
// WHEN USER SUCCESSFULLY CHOOSES LOCATION
public func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace){
let googleURL = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(place.coordinate.latitude),\(place.coordinate.longitude)&types=restaurants&radius=50000&key=MY_API_KEY"
let cityPicture = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=\(place.coordinate.latitude),\(place.coordinate.longitude)&types=locality&radius=50000&key=MY_API_KEY"
let camera = GMSCameraPosition.camera(withLatitude: place.coordinate.latitude, longitude: place.coordinate.longitude, zoom: 15)
// LIST VIEW
listViewController.cityName.removeAll()
listViewController.cityURL.removeAll()
listViewController.placeNames.removeAll()
listViewController.imageURL.removeAll()
listViewController.cityLabel.text = String(describing: place.name)
listViewController.getCityInfo(url: cityPicture)
listViewController.callAlamo(url: googleURL)
// MAP VIEW
mapViewController.mapView.camera = camera // THIS IS WHERE THE ERROR OCCURS
mapViewController.callAlamo(url: googleURL)
self.dismiss(animated: true, completion: nil)
}
// WHEN AN ERROR OCCURS
public func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error){
print("ERROR: ",error)
}
// WHEN USER PRESSES CANCEL BUTTON
public func wasCancelled(_ viewController: GMSAutocompleteViewController){
self.dismiss(animated: true, completion: nil)
}
#IBAction func openPlacePicker(_ sender: UIButton) {
let autoCompleteController = GMSAutocompleteViewController()
autoCompleteController.delegate = self
self.present(autoCompleteController, animated: true, completion: nil)
}
}
https://developer.apple.com/library/content/technotes/tn2151/_index.html
Swift code will terminate with this exception type if an unexpected condition is encountered at runtime such as:
a non-optional type with a nil List item value
a failed forced type conversion
So I could imagine that you try to work with data that is nil. Check mapViewController if it has a value.
Your tempVC is assigned to mapViewController which is never initialized.
What is the reason for having your tempXX vars? It makes your code very confusing.
In any case, change the:
var mapViewController : exploreMapsViewController!
To:
var mapViewController = exploreMapsViewController()
I created a ViewController that displays three images and other info via JSON parsing through three separate UIImageViews. When you click any of the images, it takes you to another ViewController that pop-ups a UIScrollView in the background, one UIImageView which is linked to all three images and a Button that would close the pop-up ViewController and bring it back to the previous one. Here is a screenshot. The problem I am having is that I added this code:
func removeZoom()
{
UIView.animateWithDuration(0.25, animations: {
self.view.transform = CGAffineTransformMakeScale(1.3, 1.3)
self.view.alpha = 0.0;
}, completion:{(finished : Bool) in
if (finished)
{
self.view.removeFromSuperview()
}
});
}
#IBAction func closeZoom(sender: AnyObject) {
self.navigationController?.popToRootViewControllerAnimated(true)
}
And when I try to click on the close button, nothing happens. Don't know what I am missing. Any guidance would be helpful.
Here i'll put the code for both controllers:
JnsDetail.swift
import Foundation
import UIKit
class JnsDetail: UIViewController {
#IBOutlet var tituloLabel : UILabel!
#IBOutlet var marcaLabel : UILabel!
#IBOutlet var colorLabel : UILabel!
#IBOutlet var tipoLabel : UILabel!
#IBOutlet var refLabel : UILabel!
#IBOutlet var imageView : UIImageView!
#IBOutlet var imageView2 : UIImageView!
#IBOutlet var imageView3 : UIImageView!
#IBOutlet var backbutton : UIButton!
var jsonextrct : JsonExtrct!
var photos : [String]!
var transitionOperator = TransitionOperator()
override func viewDidLoad() {
super.viewDidLoad()
//titulo = jsonextrct.titulo
tituloLabel.font = UIFont(name: mTheme.fontName, size: 21)
tituloLabel.textColor = UIColor.blackColor()
tituloLabel.text = jsonextrct.titulo
//marca = jsonextrct.marca
marcaLabel.font = UIFont(name: mTheme.fontName, size: 21)
marcaLabel.textColor = UIColor.blackColor()
marcaLabel.text = jsonextrct.marca
//color = jsonextrct.color
colorLabel.font = UIFont(name: mTheme.fontName, size: 21)
colorLabel.textColor = UIColor.blackColor()
colorLabel.text = jsonextrct.color
//tipo = jsonextrct.tipo
tipoLabel.font = UIFont(name: mTheme.fontName, size: 21)
tipoLabel.textColor = UIColor.blackColor()
tipoLabel.text = jsonextrct.tipo
//ref = jsonextrct.ref
refLabel.font = UIFont(name: mTheme.fontName, size: 21)
refLabel.textColor = UIColor.blackColor()
refLabel.text = "\(jsonextrct.ref)"
if let imageData = jsonextrct.imageData {
imageView.image = UIImage(data: imageData)
}else{
Utils.asyncLoadJsonImage(jsonextrct, imageView: imageView)
}
//topImageViewHeightConstraint.constant = 240
imageView.layer.borderColor = UIColor(white: 0.2, alpha: 1.0).CGColor
imageView.layer.borderWidth = 0.5
if let imageData2 = jsonextrct.imageData2 {
imageView2.image = UIImage(data: imageData2)
}else{
Utils.asyncLoadJsonImage(jsonextrct, imageView2: imageView2)
}
imageView2.layer.borderColor = UIColor(white: 0.2, alpha: 1.0).CGColor
imageView2.layer.borderWidth = 0.5
if let imageData3 = jsonextrct.imageData3 {
imageView3.image = UIImage(data: imageData3)
}else{
Utils.asyncLoadJsonImage(jsonextrct, imageView3: imageView3)
}
imageView3.layer.borderColor = UIColor(white: 0.2, alpha: 1.0).CGColor
imageView3.layer.borderWidth = 0.5
var tapGestureZoom = UITapGestureRecognizer(target: self, action: "zoomJns:")
tapGestureZoom.numberOfTapsRequired = 1
tapGestureZoom.numberOfTouchesRequired = 1
imageView.userInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureZoom)
var tapGestureZoom2 = UITapGestureRecognizer(target: self, action: "zoomJns2:")
tapGestureZoom2.numberOfTapsRequired = 1
tapGestureZoom2.numberOfTouchesRequired = 1
imageView2.userInteractionEnabled = true
imageView2.addGestureRecognizer(tapGestureZoom2)
var tapGestureZoom3 = UITapGestureRecognizer(target: self, action: "zoomJns3:")
tapGestureZoom3.numberOfTapsRequired = 1
tapGestureZoom3.numberOfTouchesRequired = 1
imageView3.userInteractionEnabled = true
imageView3.addGestureRecognizer(tapGestureZoom3)
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.Default
}
func backTapped(sender: AnyObject?){
dismissViewControllerAnimated(true, completion: nil)
}
#IBAction func zoomJns(sender: AnyObject?){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("JnsZoomController") as! JnsZoomController
self.modalPresentationStyle = UIModalPresentationStyle.Custom
controller.transitioningDelegate = transitionOperator
controller.jsonextrct = jsonextrct
presentViewController(controller, animated: true, completion: nil)
}
#IBAction func zoomJns2(sender: AnyObject?){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("JnsZoomController") as! JnsZoomController
self.modalPresentationStyle = UIModalPresentationStyle.Custom
controller.transitioningDelegate = transitionOperator
controller.jsonextrct = jsonextrct
presentViewController(controller, animated: true, completion: nil)
}
#IBAction func zoomJns3(sender: AnyObject?){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewControllerWithIdentifier("JnsZoomController") as! JnsZoomController
self.modalPresentationStyle = UIModalPresentationStyle.Custom
controller.transitioningDelegate = transitionOperator
controller.jsonextrct = jsonextrct
presentViewController(controller, animated: true, completion: nil)
}
}
JnsZoomController.swift
import Foundation
import UIKit
class JnsZoomController : UIViewController {
#IBOutlet var scrollView : UIScrollView!
#IBOutlet var jnsImageView : UIImageView!
#IBOutlet var jnsImageView2 : UIImageView!
#IBOutlet var jnsImageView3 : UIImageView!
var jsonextrct : JsonExtrct!
override func viewDidLoad() {
super.viewDidLoad()
if let imageData = jsonextrct.imageData {
let image = UIImage(data: imageData)
jnsImageView.image = UIImage(data: imageData)
//jnsImageView.bounds = CGRectMake(0, 0, image?.size.width, image?.size.height);
}
if let imageData2 = jsonextrct.imageData2 {
let image2 = UIImage(data: imageData2)
jnsImageView2.image = UIImage(data: imageData2)
//jnsImageView2.bounds = CGRectMake(0, 0, image?.size.width, image?.size.height);
}
if let imageData3 = jsonextrct.imageData3 {
let image3 = UIImage(data: imageData3)
jnsImageView3.image = UIImage(data: imageData3)
//jnsImageView3.bounds = CGRectMake(0, 0, image?.size.width, image?.size.height);
}
scrollView.contentSize = jnsImageView.frame.size
scrollView.contentSize = jnsImageView2.frame.size
scrollView.contentSize = jnsImageView3.frame.size
}
func removeZoom()
{
UIView.animateWithDuration(0.25, animations: {
self.view.transform = CGAffineTransformMakeScale(1.3, 1.3)
self.view.alpha = 0.0;
}, completion:{(finished : Bool) in
if (finished)
{
self.view.removeFromSuperview()
}
});
}
#IBAction func closeZoom(sender: AnyObject) {
self.navigationController?.popToRootViewControllerAnimated(true)
}
}
Here's the problem as I see it, if you are "popping" to root view controller this means that you must have PUSHED a view controller onto the navigation controller's stack and I don't see you pushing anything onto a navigation stack. Unless of course for some reason Apple decided to kill off Pushing view controllers, but I doubt this is the case. So, there's another problem with what I'm seeing in your code. You are PRESENTING view controllers by just presenting a view controller, I don't see where you are presenting a view controller by using a navigation controller to present the view controller SOOO, if you call
self.navigationController?.popToRootViewControllerAnimated(true)
then there's nothing on the stack that the navigation controller is to remove from the stack since you presented the viewcontroller modally over another viewcontroller without presenting the modal in the view controller's navigation controller.
Solution, maybe, but this isn't 100% becuase I don't have your code in front of me.
change this:
self.navigationController?.popToRootViewControllerAnimated(true)
to something like this
self.dismissViewControllerAnimated(animated: true, completion:nil)
I don't do swift so my solution is pseudo code, feel free to add the questions marks and what not that Apple decided has value for some reason.
You could also just change your presentations to this:
self.navigationController?.presentViewController(controller, animated: true, completion: nil)
Again, the above is psuedo code but I think I place the question mark in just the right spot for so that it does what it's suppose to do
Also, you can refer to this, although Apple doesn't really do a very thoroughly job of telling you how an advanced navigaiton stack works:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/#//apple_ref/occ/instm/UINavigationController/pushViewController:animated:
Sometimes you will need to have maybe 4-10 navigation controllers running at one time, so make sure you understand how they interact with view controllers and make sure you understand what POPs, PUSHes, and PRESENTs do. And good luck, have a good day.
In the closeZoom I think you should use only
#IBAction func closeZoom(sender: AnyObject) {
dismissViewControllerAnimated(true, completion: nil)
}
Because you presented that View Controller, that popToRootViewControllerAnimated(true) is used when you push it