I try to setup toolbar programmatically, but nothing of this works:
In AppDelegate
UIApplication.shared.delegate?.window??.rootViewController?.navigationController?.toolbar.isTranslucent = false
UIApplication.shared.delegate?.window??.rootViewController?.navigationController?.toolbar.tintColor = .black
In ViewDidLoad
navigationController?.toolbar.isTranslucent = false
navigationController?.toolbar.tintColor = .black
Why?
The second thing is when I navigate to another view controller, my black toolbar is shown for a moment (I hide it with navigationController?.setToolbarHidden(true, animated: true)). How can I completely hide it on transitions?
You could try subclassing UIViewController as in Apple's UIKitCatalog sample application. It uses the storyboard, but that might work for your project.
class CustomToolbarViewController: UIViewController {
#IBOutlet var toolbar: UIToolbar!
override func viewDidLoad() {
super.viewDidLoad()
let toolbarButtonItems = [
customImageBarButtonItem
]
toolbar.setItems(toolbarButtonItems, animated: true)
}
// MARK: - UIBarButtonItem Creation and Configuration
var customImageBarButtonItem: UIBarButtonItem {
// item set up code
}
Related
Xcode 10.1
Swift 4.2
I am using Master-Detail project. I need to add a bottom tab bar within the detail view but I don't want it to be displayed until an object in the Master view is selected.
Right now i used the "Hidden" option under "Drawing" for the tab bar which hides it during the initial launch, but can't find a way to make it displayed after selecting the master object.
class DetailViewController: UIViewController {
#IBOutlet weak var detailHeaderLabel: UINavigationItem!
#IBOutlet weak var detailDescriptionLabel: UILabel!
func configureView() {
// Update the user interface for the detail item.
if let detail = detailItem {
if let label = detailDescriptionLabel {
label.text = detail.description
}
if let headerLabel = detailHeaderLabel {
headerLabel.title = detail.description
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
configureView()
}
var detailItem: String? {
didSet {
// Update the view.
configureView()
}
}
}
You need to create the IBOutlet of the tabbar from storyboard and than change is hidden property
DispatchQueue.global(qos: .background).async {
// Background Thread
getObjectForMaster()
DispatchQueue.main.async {
tabBar.isHidden = false
}
}
I wrote a class that shall handle UIBarButtonItem taps.
The initializer takes a reference to an UINavigationItem. All buttons etc. are attached to this UINavigationItem. I tried to connect them with actions (didPressMenuItem()), but when I click the button, the action is not triggered (nothing is written to the console nor the breakpoint I set is triggered).
How can I link the UIBarButtonItem to the function defined in this class?
internal final class NavigationBarHandler {
// MARK: Properties
private final var navigationItem: UINavigationItem?
// MARK: Initializers
required init(navigationItem: UINavigationItem?) {
self.navigationItem = navigationItem
}
internal final func setupNavigationBar() {
if let navigationItem = navigationItem {
let menuImage = UIImage(named: "menu")?.withRenderingMode(.alwaysTemplate)
let menuItem = UIBarButtonItem(image: menuImage, style: .plain, target: self, action: #selector(didPressMenuItem(sender:)))
menuItem.tintColor = .white
navigationItem.leftBarButtonItem = menuItem
}
}
#objc func didPressMenuItem(sender: UIBarButtonItem) {
print("pressed")
}
}
This is what happens in the view controller to which navigationItem the buttons etc. are attached.
class ContactsController: UIViewController {
// MARK: View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
self.title = "Kontakte"
let navigationBarHandler = NavigationBarHandler(navigationItem: self.navigationItem)
navigationBarHandler.setupNavigationBar()
}
}
Th problem here is that you're instantiating NavigationBarHandler inside viewDidload() which is why the memory reference dies after viewDidLoad() finishes. What you should do is to create the variable outside like this.
class ContactsController: UIViewController {
var navigationBarHandler: NavigationBarHandler!
// MARK: View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
self.title = "Kontakte"
self.navigationBarHandler = NavigationBarHandler(navigationItem: self.navigationItem)
navigationBarHandler.setupNavigationBar()
}
}
This way the memory reference stays.
I have created common sidemenu for all main view controller using reference https://github.com/evnaz/ENSwiftSideMenu
Now the issue is i have created sidemenu view controller from storyboard instead of using code itself,it will not show anything on side menu.
Ideally it has to show the page which design from story board.
Actually only TableViewController work with this example. i need to work with UIViewController.
Anyone have idea about this ?
Check out the latest version, I added precisely that functionality a few weeks ago: you can now use a UIViewController, no need to use a UITableViewController.
But other than that, I can't tell without more information why it doesn't show up.
I'm using it in several apps and it works ok.
I've got a UINavigationController, which uses a subclass of ENSideMenuNavigationController, and a UIViewController for the menu itself.
This is it, basically:
class MainNavigationController: ENSideMenuNavigationController, ENSideMenuDelegate {
override func viewDidLoad() {
super.viewDidLoad()
var mainMenuViewController: MainMenuViewController = storyboard?.instantiateViewControllerWithIdentifier("MainMenuViewController") as! MainMenuViewController
mainMenuViewController.navController = self
sideMenu = ENSideMenu(sourceView: self.view, menuViewController: mainMenuViewController, menuPosition:.Right)
//sideMenu?.delegate = self //optional
sideMenu?.menuWidth = 240.0 // optional, default is 160
sideMenu?.bouncingEnabled = false
sideMenu?.animationDuration = 0.2
// make navigation bar showing over side menu
view.bringSubviewToFront(navigationBar)
}
// MARK: - ENSideMenu Delegate
func sideMenuWillOpen() {
println("sideMenuWillOpen")
}
func sideMenuWillClose() {
println("sideMenuWillClose")
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
super.didRotateFromInterfaceOrientation( fromInterfaceOrientation )
sideMenu?.updateFrame()
}
}
Then I have the menu view itself, also in the Storyboard, which is a UIViewController. Here is a fragment:
class ERAMainMenuViewController: UIViewController {
weak var navController: ERAMainNavigationController?
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var exitButton: UIButton!
#IBOutlet weak var headImage: UIImageView!
let kInset:CGFloat = 64.0
override func viewDidLoad() {
super.viewDidLoad()
// Customize apperance of table view
tableView.contentInset = UIEdgeInsetsMake(kInset, 0, 0, 0) //
tableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
tableView.backgroundColor = ERAssistantTheme.sideMenuItemBackgroundColor
tableView.scrollsToTop = false
// Preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = true
// tableView.selectRowAtIndexPath(NSIndexPath(forRow: selectedMenuItem, inSection: 0), animated: false, scrollPosition: .Middle)
}
}
I try to create a toolbar with a UIBarButtonItem with a customView (UISwitch). This is done by my function "createtoolbar()".
On viewDidLoad() the toolbar is created properly.
BUT: Creating the toolbar by pressing a Button, the UISwitch disappears approx. 0.1 seconds later.
Hope someone can help me! :)
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
createtoolbar()
}
#IBOutlet var bottomBar: UIToolbar!
let alarmSwitch = UISwitch()
func createtoolbar() {
alarmSwitch.on = true
let alarmSwitchBarButton = UIBarButtonItem(customView: alarmSwitch)
var toolbarbuttons = [alarmSwitchBarButton]
bottomBar.setItems(toolbarbuttons, animated: true)
}
#IBAction func createtoolbarButtonPressed(sender: AnyObject) {
createtoolbar()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
It's unclear what you're trying to do. You're creating the bar button item in code but adding a switch that's an IBOutlet? You can't do that -- if your switch actually is an IBOutlet, then it will already be the subview of some other view, and you can't use it in you bar button. If it's not an IBOutlet (which to shouldn't be), then you need to create the switch in code.
I've implemented an edit burron for my custom tableviewcontroller without using the default edit button. I have put a UIBarButton item in my storyboard and linked with IBOutlet in my custom class. I've implemented all these simple mechanisms for changing the button title:
class DetailTableViewController: UITableViewController {
var selectedMedicine: NSManagedObject?
var edit: Bool = false
#IBOutlet var editButton: UIBarButtonItem
#IBOutlet var nameTextField: UITextField
#IBOutlet var noteTextView: UITextView
#IBAction func enableEditing(sender: AnyObject) {
if !edit
{
println("editing")
self.edit = true
self.navigationItem.rightBarButtonItem.title = "Done"
}
else
{
self.edit = false
self.navigationItem.rightBarButtonItem.title = "Edit"
}
}
The title changes but there's something strange in the transition from Edit to Done because it's a little jerky.
I've found another one with my same problem but no one answered him.
You can look at this video for undertsand the bad animation i mean video
Instead of manually setting the bar button title and tracking state, you can use the built-in UIViewController.editButtonItem and UIViewController.editing property:
func viewWillAppear(animated:Bool) {
self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
#IBAction func enableEditing(sender: AnyObject) {
self.editing = !self.editing
}