Navigation controller delays before pushing to View Controller - ios

I have a View Controller A with a collection view with list of items. I have to push to another View controller B.
When I select an item in Collection View I want this push to occur. But the push happens after a slight delay which I want to avoid.
I have had few lines of code after didSelect Item method and also NavigationController's navigation Bar setup and CollectionView setup in the View Did load and View Will Appear methods of the View Controller B.
I tried removing the codes after CollectionView Did Select just to check if this was causing the delay but the animation is still slow.
View Controller A Code.
DispatchQueue.global(qos: .background).async {
DispatchQueue.main.async {
//write your code here
var dict = projectsArray[indexPath.row - 1] as! [String:Any]
guard let id = dict["_id"] as? NSNumber else{return }
var canvasIds = NSArray()
if let idsAll = projectCanvasIds.object(forKey: id.stringValue) as? NSArray{
canvasIds = idsAll
}
dict["CanvasIds"] = canvasIds
let dict2 = dict as NSDictionary
IndexContentsModel.projectSlectedCanvasIds = dict2.mutableCopy() as! NSMutableDictionary
let vc = IndexCanvasViewController(nibName: "IndexCanvasViewController", bundle: nil)
self.navigationController?.pushViewController(vc, animated: true)
}
}
View Controller B Code
View Did Load has CollectionViewInit() and SetUI()
func collectionViewinit(){
let nib = UINib(nibName: "TopCanvasesCollectionViewCell", bundle: nil)
self.collectionView.register(nib, forCellWithReuseIdentifier: "topCanvasCell")
collectionView.register(UINib(nibName: "CanvasViewCollectionReusableView3", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "canvasHeaderView")
}
func setUI(){
self.navigationController?.navigationItem.hidesBackButton = true
self.navigationController?.navigationBar.clipsToBounds = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let hostStr = host
let userinfo = UserInfo.shared()
if let photo = userinfo?.dicJSON.object(forKey: "photo") as? String{
let profile = host + photo
imgView.sd_setImage(with: URL(string: profile), completed: nil)
}else{
imgView.image = UIImage(named: "test_Profile")
}
let button = UIButton()
button.addTarget(self, action:#selector(profileViewButtonPressed(_:)), for: UIControlEvents.touchUpInside)
button.frame = CGRect(x: 0, y: 0, width: 36, height: 36)// CGRectMake(0, 0, 36, 36)
button.layer.cornerRadius = button.frame.width / 2
button.layer.masksToBounds = true
button.setImage(imgView.image, for: UIControlState.normal)
// let profileButton = UIBarButtonItem(customView: button)
let searchImage = UIImage(named: "Search_Icon3")!
let notificationImage = UIImage(named: "Notification_Icon3")!
let profileImage = UIImage(named: "test_Profile")!
let backImage = UIImage(named: "Back_Icon3")!
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(searchViewButtonPressed(_:)))
let notificationButton = UIBarButtonItem(image: notificationImage, style: .plain, target: self, action: #selector(notificationViewButtonPressed(_:)))
let profileButton = UIBarButtonItem(image: profileImage, style: .plain, target: self, action: #selector(profileViewButtonPressed(_:)))
let backButton = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(backButtonPressed(_:)))
self.navigationItem.rightBarButtonItems = [profileButton,notificationButton,searchButton]
self.navigationController?.navigationBar.tintColor = UIColor(hexString: "#373839")
self.navigationItem.leftBarButtonItem = backButton
self.setValues()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = false
self.navigationController?.navigationItem.largeTitleDisplayMode = .never
self.navigationController!.navigationBar.backgroundColor = UIColor.white
} else {
// Fallback on earlier versions
}
if (self.isBeingPresented || self.isMovingToParentViewController) {
self.collectionView.animateViews(animations: animationsCanvas, reversed: false, initialAlpha: 0, finalAlpha: 1, delay: 0, duration: 0.07, animationInterval: 0.1, completion: nil)
}
}

Related

Keyboard (numpad) toolbar working but not showing

I tried to add a toolbar for my UITextFiled, the keyboard is set to numpad. It is working but the button is not showing. I created an extension for my UITextfield
extension UITextField {
/// Adding a done button on the keyboard
func addDoneButtonOnKeyboard() {
let doneToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))
let items = [flexSpace, done]
doneToolbar.items = items
doneToolbar.sizeToFit()
self.inputAccessoryView = doneToolbar
}
/// Done button callback
#objc func doneButtonAction() {
self.resignFirstResponder()
}
}
and then I am calling this extension like this
private lazy var fromInputField: CoinpassInput = {
let input = CoinpassInput()
input.keyboardType = .decimalPad
input.addTarget(self, action: #selector(fromInputFieldDidChange), for: .editingChanged)
input.addDoneButtonOnKeyboard()
return input
}()
the toolbar is showing and working but the 'done; button is not showing. If I click on the right corner of the toolbar. the keyboard will hide. I dont know what I am missing why the button is not showing.
Try this code, with slight modifications:
func addDoneButtonOnKeyboard() {
let doneToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
doneToolbar.barTintColor = .red
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))
done.tintColor = .yellow
doneToolbar.setItems([flexSpace,done], animated: false)
doneToolbar.isUserInteractionEnabled = true
self.inputAccessoryView = doneToolbar
}

Not able to display barbutton items on navigation bar in swift 4.2 when connected to tabbarcontroller?

I have linked both navigationController and tabBarController like this
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = mainStoryboard.instantiateViewController(withIdentifier: "TabAction") as UIViewController
self.window = UIWindow(frame: UIScreen.main.bounds)
self.window?.rootViewController = UINavigationController(rootViewController: TabBarController())
self.window?.makeKeyAndVisible()
let navigationController = UINavigationController.init(rootViewController: viewController)
UIApplication.shared.keyWindow?.rootViewController = viewController
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
code for barbutton item in view controller:
super.viewDidLoad()
// registering table
recruitmentDbView?.register(UINib(nibName: "recruitmentDashboardCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
// setting colour to navigation bar
self.navigationController?.navigationBar.barTintColor = UIColor(red: 18/255, green: 41/255, blue: 50/255, alpha: 1)
// setting barbutton items on navigation bar
let rightFilterBarButtonItem: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "FilterIcon"), style: .plain, target: self, action: nil)
rightFilterBarButtonItem.tintColor = UIColor.white
let rightSearchBarButtonItem: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "SearchIcon"), style: .plain, target: self, action: nil)
rightSearchBarButtonItem.tintColor = UIColor.white
self.navigationItem.rightBarButtonItems = [rightFilterBarButtonItem,rightSearchBarButtonItem]
self.navigationItem.leftBarButtonItem?.isEnabled = true
self.navigationItem.backBarButtonItem?.isEnabled = false
let leftBackBarButtonItem: UIBarButtonItem = UIBarButtonItem(image: UIImage(named: "BackIcon"), style: .plain, target: self, action: nil)
self.navigationItem.leftBarButtonItem = leftBackBarButtonItem
self.navigationItem.title = "Recruit - Dashboard"
let textAttributes = [NSAttributedString .Key.foregroundColor:UIColor.white]
self.navigationController?.navigationBar.titleTextAttributes = textAttributes
}
Try This code:-
let button1 = UIBarButtonItem(image: UIImage(named: "imagename"), style: .plain, target: self, action: selector: #selector(action1)) //
self.navigationItem.rightBarButtonItem = button1
let filterIcon = UIImage(named: "FilterIcon")!
let searchImage = UIImage(named: "SearchIcon")!
let rightFilterBarButtonItem = UIBarButtonItem(image: filterIcon, style: .Plain, target: self, selector: #selector(action2))
let rightSearchBarButtonItem = UIBarButtonItem(image: searchImage, style: .Plain, target: self, selector: #selector(action3))
navigationItem.rightBarButtonItems = [rightFilterBarButtonItem, rightFilterBarButtonItem]
#objc func action1()
{
}
#objc func action2()
{
ProgressViewVc.sharedInstance.showProcessView()
}
#objc func action3()
{
ProgressViewVc.sharedInstance.showProcessView()
}

Navigation Bar stays while Pushing and Poping the View Controllers creating a weird White color Effect while transition

I have a navigationController which is being used to move between my ViewControllers.
I have it setup normally and I am using Xib's for each View Controller.
extension UINavigationController{
func setup(){
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationItem.largeTitleDisplayMode = .always
} else {
// Fallback on earlier versions
}
self.navigationBar.isTranslucent = true
self.view.backgroundColor = UIColor.red
self.navigationBar.clipsToBounds = true
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.tintColor = UIColor(hexString: "#373839")
}
}
This is the extension I am using for my UINavigation Controller.
And in the pushed View (Second View), I need to have different Left and right buttons so I am hiding the navigation backbitten and having a custom code to setup my buttons.
func setUI(){
self.navigationController?.navigationItem.hidesBackButton = true
self.navigationController?.navigationBar.clipsToBounds = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
let hostStr = host
print(hostStr)
let searchImage = UIImage(named: "Search_Icon3")!
let notificationImage = UIImage(named: "Notification_Icon3")!
let profileImage = UIImage(named: "test_Profile")!
let backImage = UIImage(named: "Back_Icon3")!
let searchButton = UIBarButtonItem(image: searchImage, style: .plain, target: self, action: #selector(searchViewButtonPressed(_:)))
let notificationButton = UIBarButtonItem(image: notificationImage, style: .plain, target: self, action: #selector(notificationViewButtonPressed(_:)))
let profileButton = UIBarButtonItem(image: profileImage, style: .plain, target: self, action: #selector(profileViewButtonPressed(_:)))
let backButton = UIBarButtonItem(image: backImage, style: .plain, target: self, action: #selector(backButtonPressed(_:)))
self.navigationItem.rightBarButtonItems = [profileButton,notificationButton,searchButton]
self.navigationController?.navigationBar.tintColor = UIColor(hexString: "#373839")
self.navigationItem.leftBarButtonItem = backButton
self.setValues()
}
But when I push from ViewController 1 to 2 and Pop from 2 to 1 I get this weird Nav bar present effect between transition

UINavigationItem not displaying left and right barButtons

I'm testing my app on an iPhone 6+. I have a navigation bar which includes two labels, a left bar button (not shown initially), and a right bar button. The problem is that the labels are shown but no matter how hard I try I can't make it show the buttons. They work(if you tap on where they should be, they work as expected) but are not shown. The tests on an iPhone 5s (physic) and iPhone X (simulator) went correctly and the buttons are shown.
Is there any problem with my code?
Thank you.
override func viewDidLoad() {
super.viewDidLoad()
webView.delegate = self
loadWeb()
let button = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.action, target: self, action: #selector(share))
button.tintColor = UIColor.white
self.navigationItem.rightBarButtonItem = button
let frameLabelURLTitle = CGRect.init(x: 25, y: 2, width: (self.navigationController?.navigationBar.frame.size.width)! - 182, height: (self.navigationController?.navigationBar.frame.size.height)! - 20)
let frameLabelURL = CGRect.init(x: 25, y: 2 + frameLabelURLTitle.height, width: (self.navigationController?.navigationBar.frame.size.width)! - 182, height: 10)
let viewLabel = UIView.init(frame: frameLabelURLTitle)
labelTitleURL = UILabel.init(frame: frameLabelURLTitle)
labelURL = UILabel.init(frame: frameLabelURL)
labelURL.textColor = UIColor.white
labelTitleURL.textColor = UIColor.white
labelURL.font = UIFont.systemFont(ofSize: 13.0)
viewLabel.addSubview(labelTitleURL)
viewLabel.addSubview(labelURL)
self.navigationController?.navigationBar.addSubview(viewLabel)
loadingLabel.text = "loadingWeb".localized()
loadingLabel.sizeToFit()
self.navigationController?.isNavigationBarHidden = true
self.placeHolderView.layer.insertSublayer(initGradient(bounds: self.view.bounds, isHorizontal: false), at: 0)
self.loadingGifImageView.image = UIImage.gif(asset: "01-GIF_LOGO")
}
func webViewDidFinishLoad(_ webView: UIWebView) {
self.placeHolderView.isHidden = true
self.navigationController?.isNavigationBarHidden = false
labelTitleURL.text = webView.stringByEvaluatingJavaScript(from: "document.title")
labelURL.text = webView.request?.url?.absoluteString.components(separatedBy: "/")[2]
self.navigationItem.leftBarButtonItem = nil
if !(webView.request?.url?.absoluteString.contains("/blog/"))! {
let newBackButton = UIBarButtonItem(image: UIImage(named: "bt_close")?.withRenderingMode(.alwaysOriginal), style: UIBarButtonItemStyle.plain, target: self, action: #selector(back))
newBackButton.isEnabled = true
print(newBackButton.style)
self.navigationItem.setLeftBarButton(newBackButton, animated: true)
self.navigationItem.leftBarButtonItem = newBackButton
self.navigationItem.backBarButtonItem = newBackButton
}
}

Reloading a UINavigationItem

I want to load my view controller with one navItem.rightBarButtonItem and change it to another based on a set of circumstances. It seems as if I can only load it once, on viewDidLoad. Is there a method for updating a bar button item after you've changed the icon?
func viewDidLoad() {
var iconOne = UIImage(named: "button")
let buttonOne = UIBarButtonItem(image: iconOne, style: UIBarButtonItemStyle.Plain, target: self, action: "funcOne")
self.navItem.rightBarButtonItem = buttonOne
//perform async query, if a condition holds true then:
var iconTwo = UIImage(named: "buttonTwo")
let buttonTwo = UIBarButtonItem(image: iconTwo, style: UIBarButtonItemStyle.Plain, target: self, action: "funcTwo")
self.navItem.rightBarButtonItem = buttonTwo
}
Full code:
override func viewDidLoad() {
super.viewDidLoad()
// Sets custom nav bar view so we can add multiple bar buttons
navBar = UINavigationBar(frame: CGRectMake(0, 20, UIScreen.mainScreen().bounds.size.width, 44))
navBar.barTintColor = UIColor.blackColor() // Sets bar to black
navBar.translucent = false
self.view.addSubview(navBar)
navItem = UINavigationItem(title: "\(name)") // Sets title
navBar.titleTextAttributes = [ NSFontAttributeName: UIFont(name: "Helvetica Neue", size: 25)!, NSForegroundColorAttributeName: UIColor.whiteColor()]
// Set icons
var backIcon = UIImage(named: "backButton")
let backButton = UIBarButtonItem(image: backIcon, style: UIBarButtonItemStyle.Plain, target: self, action: "backButton")
navItem.leftBarButtonItem = backButton
var userQuery = PFQuery(className: "Followers")
userQuery.whereKey("following", equalTo: username)
userQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if error == nil {
if let objects = objects {
for object in objects {
if let follower = object["follower"] as? String {
if follower == PFUser.currentUser()!.username! {
var followingIcon = UIImage(named: "followingButton")
let followingButton = UIBarButtonItem(image: followingIcon, style: UIBarButtonItemStyle.Plain, target: self, action: "unfollowUser")
self.navItem.rightBarButtonItem = followingButton
self.navItem.rightBarButtonItem?.tintColor = UIColor.orangeColor()
} else {
var followIcon = UIImage(named: "followButton")
let followButton = UIBarButtonItem(image: followIcon, style: UIBarButtonItemStyle.Plain, target: self, action: "followUser")
self.navItem.rightBarButtonItem = followButton
self.navItem.rightBarButtonItem?.tintColor = UIColor.darkGrayColor()
}
}
}
}
} else {
println(error)
}
})
I'm not sure if this is possible. So, I made my own custom view where each bar button item would be. I set my right bar button item at var rightButton = UIButton(frame: CGRectMake(UIScreen.mainScreen().bounds.width - 50, 25, 30, 30)), added an action, and added the subview to the view.

Resources