Swift - Cannot pass value successfully to the ViewController that is presented next - ios

I have an ItemsController and I want to pass a value to the RepostController when using self.navigationController?.pushViewController(destination, animated: true) to present the RepostController. I want to set the itemId of the RepostController to be cell.item!.getId(). But in the RepostController, I always get a value of 0 from the itemId. I have also tried to print the values. They are commented in the codes below.
I'm using Swift 4 with Xcode 10.1.
// ITEMS CONTROLLER
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor(red:0.30, green:0.30, blue:0.30, alpha:1.0)]
self.navigationController?.navigationBar.tintColor = UIColor(red:0.30, green:0.30, blue:0.30, alpha:1.0)
self.navigationController?.navigationBar.shadowImage = UIImage()
tableView.estimatedRowHeight = 250
tableView.rowHeight = UITableView.automaticDimension
DispatchQueue.main.async() {
self.refresh(sender: self)
self.tableView.reloadData()
}
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
}
if ((profileId == iApp.sharedInstance.getId() && pageId == Constants.ITEMS_PROFILE_PAGE) || pageId == Constants.ITEMS_FEED_PAGE || pageId == Constants.ITEMS_STREAM_PAGE) {
let newItemButton = UIBarButtonItem(barButtonSystemItem: .add , target: self, action: #selector(newItem))
self.navigationItem.rightBarButtonItem = newItemButton
}
// add tableview delegate
tableView.delegate = self
tableView.dataSource = self
self.tableView.tableFooterView = UIView()
self.refreshControl.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged)
self.tableView.addSubview(refreshControl)
self.tableView.alwaysBounceVertical = true
// prepare for loading data
self.showLoadingScreen()
// start loading data
self.loadData()
}
func showRepostButton(cell: ItemCell) {
let storyboard = UIStoryboard(name: "Content", bundle: Bundle.main)
let destination = storyboard.instantiateViewController(withIdentifier: "RepostController") as! RepostController
destination.itemId = cell.item!.getId()
print (String(cell.item!.getId())) // Whatever the correct value is (such as 20)
self.navigationController?.pushViewController(destination, animated: true)
}
// REPOST CONTROLLER
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor:UIColor(red:0.30, green:0.30, blue:0.30, alpha:1.0)]
self.navigationController?.navigationBar.tintColor = UIColor(red:0.30, green:0.30, blue:0.30, alpha:1.0)
textView.delegate = self
textView.tintColor = UIColor(red:0.23, green:0.72, blue:0.65, alpha:1.0)
print ("itemID:" + String(self.itemId))
}
#IBAction func cancelTap(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
#IBAction func repostTap(_ sender: Any) {
self.message = self.textView.text
send()
}
I need the value to be passed to the RepostController successfully.
What changes do I need to make? Thanks!

What I would do is create a PUSH segue in IB. Then in the prepare(forSegue:) method:
if let dest = segue.destination as? YourDestinationVC {
dest.itemId = someValue
}

Related

NavigationBar title text won't change with titleTextAttributes

I have a strange issue which I don't really understand.
I have two views, one should have a black title and the other should have a white title.
The issue that I am experiencing is that I can set the color ONCE and not change it back.
So when I go to the view that has the white title from the view with the black title and then go back, the title does not change back to black.
code for white title in viewWillAppear:
self.navigationController?.navigationBar.barStyle = .black
self.navigationController?.navigationBar.tintColor = .white
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
code for black title in viewWillAppear:
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.navigationBar.tintColor = UIColor.blue
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]
Why does it not change back, when I am clearly setting a new color?
EDIT: adding the complete code
Black title view:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.navigationBar.tintColor = hexStringToUIColor(hex: "4CAF50")
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]
self.navigationItem.title = listData.name
clearStatusBarColor()
let editButton = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(tapToEdit))
let sortImg = UIImage(named: "sort")
sortingButton = UIBarButtonItem(image: sortImg, style: .plain, target: self, action: #selector(tapToSort))
self.navigationItem.rightBarButtonItems = [sortingButton!, editButton]
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = nil
// get updated Data
if User.active.hasListUpdated {
// return with new gameEntries -> Update
listData = User.active.allLists![listDataIndex] // To keep upToDate data!
listEntries = listData.list_entries!
gameEntries = listEntries.compactMap({ (entry: ListEntry) -> GameEntry in
return GameEntry(game: entry.game, platform: nil, platform_id: entry.platform, rating: Int(entry.rating ?? 0), review: nil, notes: entry.description)
})
listTable.reloadData()
}
// Sorting
if hasSortChanged {
hasSortChanged = false
sortList(sort: sortingOption, order: sortingOrder)
}
}
White title view:
override func viewWillAppear(_ animated: Bool) {
if !isPreviewing {
self.navigationController?.navigationBar.isHidden = false
self.navigationController?.navigationBar.barStyle = .black
self.navigationController?.navigationBar.tintColor = .white
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
// MARK: Clear StatusBar
clearStatusBarColor()
if transparentNav {
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for:UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.title = nil
} else {
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = nil
self.title = game.name!
}
}
// MARK: NavigationBar
let button = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(showOptions))
self.navigationItem.rightBarButtonItem = button
// Check if game should have new review or rating
if User.active.hasMainScreenUpdated {
// Update rating
updateUserRating()
// update review
updateUserReviewStatus()
}
// Update lists!
if User.active.hasListUpdated {
updateListsStatus()
}
}
If you are changing the nav bar colors in different view controllers, I recommend you to have a subclass of UIViewController and handle the navbar changes through that. Here's an example for your case.
class CustomUIViewController: UIViewController {
override func didMove(toParentViewController parent: UIViewController?) {
super.didMove(toParentViewController: parent)
if parent == nil {
if SettingsManager.LastBarColor == .default {
self.setLightBars()
}
else {
self.setDarkBars()
}
}
}
func setDarkBars() {
SettingsManager.LastBarColor = .lightContent
UIApplication.shared.statusBarStyle = UIStatusBarStyle.lightContent
tabBarController?.tabBar.tintColor = UIColor.white
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
}
func setLightBars() {
SettingsManager.LastBarColor = .default
UIApplication.shared.statusBarStyle = UIStatusBarStyle.default
tabBarController?.tabBar.tintColor = UIColor.Black
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.Black]
navigationController?.navigationBar.barTintColor = UIColor.white
navigationItem.titleView?.tintColor = UIColor.Black
}
}
class SettingsManager {
class var LastBarColor: UIStatusBarStyle = .default
}
And in your view controller use CustomUIViewController, call setDarkBars() or setLightBars() in your viewWillAppear() function.
You can use a custom UINavigationController class then override pushViewController function to set what you need on the navigationBar.
The viewWillAppear method has a lot of code here.
class MyNavigationViewController: UINavigationController {
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
super.pushViewController(viewController, animated: animated)
self.updateForVC(viewController: viewController)
}
func updateForVC(viewController: UIViewController) {
//DO WHATEVER YOU WHANT HERE, title, img, etc
var color = UIColor.black
if viewController.isKind(of: MyClass.self) {
color = UIColor.white
}
self.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: color]
}
}
Try pushViewController to navigate,It is working for me
if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController {
if let navigator = self.navigationController {
navigator.pushViewController(viewController, animated: true)
viewController.title = ""
}
}

IOS UISegmentedControl doesn't not display in ios 10

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.

Search bar issue ios 11, refresh control

Im adding refresh control to tableView.
then start animate it from code dosent show on top. I must scroll tableView to down.
And after this i add Search controll to navbaritem then its look like:
here is code
lazy var customRefreshControl: UIRefreshControl = {
let control = UIRefreshControl()
control.attributedTitle = NSAttributedString(string: "Downloading Locations")
control.addTarget(self, action: #selector(updateLocation), for: .valueChanged)
return control
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.largeTitleDisplayMode = .automatic
searchController = UISearchController(searchResultsController: nil)
searchController.searchBar.tintColor = .white
searchController.searchBar.delegate = self
tableView.addSubview(customRefreshControl)
title = "location_groups".localized()
tableView.tableFooterView = UIView()
tableView.backgroundColor = .groupTableViewBackground
navigationItem.searchController = searchController
searchController.dimsBackgroundDuringPresentation = false
}
func loadLocationGroups() {
DispatchQueue.global(qos: .userInteractive).async { [unowned self] in
self.locationGroups = DataBaseManager.Instance.GetLocations()
DispatchQueue.main.async {
self.tableView.reloadData()
if self.locationGroups.isEmpty {
self.customRefreshControl.attributedTitle = NSAttributedString(string: "Downloading Locations")
} else {
self.customRefreshControl.attributedTitle = NSAttributedString(string: "Synchronize")
}
self.customRefreshControl.beginRefreshing()
}
self.request(requestType: .getLocationGroups)
}
}

InputView of the SlackTextViewController is behind keyboard

I'm using the SlackTextViewController.
Before It works fine but now I got a problem.
When I tapped inputView of SlackTextViewController then Keyboard will be displayed.
But InputView is not following up keyboard. So I cant see InputView after keyboard showing up.
Here is snippet code.
class CommentVC: SLKTextViewController {
override var tableView: UITableView {
get {
return super.tableView!
}
}
override class func tableViewStyle(for decoder: NSCoder) -> UITableViewStyle {
return .plain
}
override func viewDidLoad() {
super.viewDidLoad()
//Do any additional setup after loading the view, typically from a nib.
let cellNib = UINib(nibName: "CommentTableCell", bundle: Bundle.main)
tableView.register(cellNib, forCellReuseIdentifier: "CommentTableCell")
//Set Title at the top
self.navigationController?.isNavigationBarHidden = false
self.navigationItem.title = "Comments"
self.navigationItem.hidesBackButton = true
let backButton = UIBarButtonItem(image: UIImage(named: "backBtn"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(CommentVC.back(_:)))
self.navigationItem.leftBarButtonItem = backButton
self.navigationItem.leftBarButtonItem?.setBackgroundVerticalPositionAdjustment(-8, for: UIBarMetrics.default)
// SLKTVC's configuration
self.bounces = true
self.shakeToClearEnabled = true
self.isKeyboardPanningEnabled = true
self.shouldScrollToBottomAfterKeyboardShows = false
self.isInverted = false
}
override func didChangeKeyboardStatus(_ status: SLKKeyboardStatus) {
switch status {
case .willShow:
print("Will Show")
case .didShow:
print("Did Show")
case .willHide:
print("Will Hide")
case .didHide:
print("Did Hide")
}
}
}
My problem is didKeyboardChangeStatus is not called.
It does not working in iOS 10 and iOS 11.

UISegmented Control hides below the UINavigationController

I have a firstViewController which has a UISegmentedControl and SegmentedControl has two tabs button. its all working fine but when i go to next SecondViewController. On SecondViewController there is a link for webView when i push to that webView & then back to SecondViewController and then back to firstViewController by tapping back button. The SegmentedControl leave its position & it moves below the NavigationController
firstViewController Code is :
override func viewDidLoad() {
super.viewDidLoad()
setupMenuBar()
setupViewControllerUI()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupNavigationBarUI()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewDidAppear(animated)
// to avoid getting a black navigationBar while transition
navigationController?.navigationBar.barTintColor = UIColor.white
self.navigationController?.navigationBar.setBackgroundImage(UIColor.white.convertImage(), for: UIBarMetrics.default)
navigationController!.navigationBar.titleTextAttributes = [ NSFontAttributeName: UIFont.appThemeRegularFontWithSize(20.0), NSForegroundColorAttributeName: UIColor.lightGray]
}
// MARK: - UIViewController Helper Method
func setupViewControllerUI() {
if isFirstVC {
AppUtility.switchToViewController(viewController: firstViewController!, in: self)
segmentedControl.selectedSegmentIndex = 0
} else {
LoadingViewController.sharedLoader.showLoading(self.navigationController!)
AppUtility.switchToViewController(viewController: secondViewController, in: self)
segmentedControl.selectedSegmentIndex = 1
}
}
func setupMenuBar() {
SegmentedControlContainerView.backgroundColor = UIColor.ButtonColorWithAlpha(1.0)
segmentedControl.tintColor = UIColor.white
}
func setupNavigationBarUI() {
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white]
navigationController?.navigationBar.barTintColor = UIColor.ButtonColorWithAlpha(1.0)
navigationController?.navigationBar.setBackgroundImage(UIColor.ButtonColorWithAlpha(1.0).convertImage(), for: UIBarMetrics.default)
navigationController?.navigationBar.shadowImage = UIColor.white.withAlphaComponent(0.0).convertImage()
navigationController?.view.backgroundColor = UIColor.ButtonColorWithAlpha(1.0)
segmentedControl.setTitle("first", forSegmentAt: 1)
segmentedControl.setTitle("second", forSegmentAt: 0)
self.navigationController?.navigationBar.tintColor = UIColor.white
navigationController?.navigationBar.barStyle = UIBarStyle.default
self.title = "Screen Name"
navigationController?.navigationBar.setNeedsDisplay()
}

Resources