UIBarButtonItems Spacing Issue in iOS 11 - swift4

I'm trying to adjust spacing between UIBar Button items.
func addLeftBarButtonItems() {
let btn1 = UIButton(type: UIButton.ButtonType.custom) as UIButton
let list_icon = UIImage(named: "list") as UIImage?
btn1.setImage(list_icon, for: UIControl.State.normal)
let item1 = UIBarButtonItem()
item1.customView = btn1
let btn2 = UIButton()
btn2.setTitle("Notification", for: .normal)
btn2.setTitleColor(UIColor.black, for: .normal)
let item2 = UIBarButtonItem()
item2.customView = btn2
let btn3 = UIButton(type: UIButton.ButtonType.custom) as UIButton
let redbadge = UIImage(named: "red_badge") as UIImage?
btn3.setBackgroundImage(redbadge, for: UIControl.State.normal)
btn3.setTitle("10", for: .normal)
btn3.titleLabel?.font = .systemFont(ofSize:10)
btn3.setTitleColor(UIColor.black, for: .normal)
let item3 = UIBarButtonItem()
item3.customView = btn3
let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
space.width = -8
self.navigationItem.leftBarButtonItems = [ item1, item2 , space ,item3]
}
How to reduce/increase the gap between the Notification title and the badge icon and . The fixed space dosen't seem to work .

Negative value for spacing does not work. However positive values do.

Related

Buttons in collectionViewCell not triggering functions

I created a button in a supplementary collectionView cell as header and added a button with a target to it but it doesn't trigger the function when tapped. What am I doing wrong?
Below is the button I created and its target function in the cell class.
let dummyButton :UIButton = {
let button = UIButton(type: .system)
button.setTitle("Dummy", for: .normal)
button.layer.cornerRadius = 3
button.layer.borderWidth = 1
button.titleLabel?.font = UIFont.systemFont(ofSize: 12)
button.tintColor = UIColor.brown
button.addTarget(self, action: #selector(handleTrash), for: .touchUpInside)
return button
}()
#objc func handleTrash (){
print("It worked this time around so what was going on?")
}
I wrote all these in the collectionView Cell subclass. Please help
I found the solution. I had to declare the buttons as Lazy variables.
Add the sender
button.addTarget(self, action: #selector(handleTrash(_:)), for: .touchUpInside)
#objc func handleTrash (_ sender: UIButton){
print("It worked this time around so what was going on?")
}

How can I use different type of cell in collection view?

I am trying create an app about social network. In there users can send two different type post (like image post or text post). Users selecting of their post type in another controller and create their post. I Created two different cell and want to call in cellForItemAt with if statement. The problem is how can I know users selection about post type ?
// there is users post type selection with button
let writeButton: UIButton = {
let wButton = UIButton()
wButton.layer.cornerRadius = 7
wButton.setBackgroundImage(#imageLiteral(resourceName: "writing"), for: .normal)
wButton.setTitle("Writing", for: .normal)
wButton.setTitleColor(UIColor.white, for: .normal)
wButton.titleLabel?.font = UIFont(name: "AvenirNext-DemiBoldItalic", size: 18)
wButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
wButton.layer.borderWidth = 1.5
wButton.addTarget(self, action: #selector(tappedWriteButton), for: .touchUpInside)
return wButton
}()
#objc func tappedWriteButton () {
let writePost = WriteTitlePost()
navigationController?.pushViewController(writePost, animated: true)
}
let mediaButton: UIButton = {
let mButton = UIButton()
mButton.layer.cornerRadius = 7
mButton.backgroundColor = UIColor.orange
mButton.setBackgroundImage(#imageLiteral(resourceName: "photography"), for: .normal)
mButton.setTitle("Media Post", for: .normal)
mButton.setTitleColor(UIColor.white, for: .normal)
mButton.titleLabel?.font = UIFont(name: "AvenirNext-DemiBoldItalic", size: 18)
mButton.layer.borderWidth = 1.5
mButton.layer.borderColor = UIColor.orange.cgColor
mButton.heightAnchor.constraint(equalToConstant: 60).isActive = true
mButton.addTarget(self, action: #selector(tappedMediaButton), for: .touchUpInside)
return mButton
}()
#objc func tappedMediaButton() {
let layout = UICollectionViewFlowLayout()
let mediaPost = MediaPost(collectionViewLayout: layout)
let navController = UINavigationController(rootViewController: mediaPost)
present(navController, animated: true, completion: nil)
}

Going back to the previous page programatically

enter image description hereI am making a user login page for my IOS App. I am trying to make everything programmatically without using a segue in the main story board. I have managed to go to the next page as you can see in the code and create a custom left back bar item. But I don't know how to go back to the first page when I click on that button. I have attached the screen shot of my story board and app below. Can you please tell me how I can go back to the first page by clicking the X button?
Here is my code:
import UIKit
class FirstPage: UIViewController {
let hgt = UIScreen.main.bounds.height/2
private let loginSignup: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Login or Sign Up", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
button.setTitleColor(.green, for: .normal)
button.addTarget(self, action: #selector(loginSignupBtn), for: .touchUpInside)
return button
}()
#objc private func loginSignupBtn() {
let vc = self.storyboard!.instantiateViewController(withIdentifier: "Login") as! Login
vc.loadViewIfNeeded()
self.navigationController?.pushViewController(vc, animated: true)
self.navigationController?.isNavigationBarHidden = false
let backItem = UIBarButtonItem(title: "X ", style: UIBarButtonItem.Style.done, target: nil, action: nil)
let font = UIFont.boldSystemFont(ofSize: 26)
backItem.setTitleTextAttributes([NSAttributedString.Key.font:font] ,for: .normal)
backItem.tintColor = UIColor.green
vc.navigationItem.leftBarButtonItem = backItem
}
override func viewDidLoad() {
super.viewDidLoad()
setupLayout()
}
override func viewWillAppear(_ animated: Bool) {
}
private func setupLayout() {
let topImageContainerView = UIView()
//topImageContainerView.backgroundColor = .yellow
view.addSubview(topImageContainerView)
//enable auto layout
topImageContainerView.translatesAutoresizingMaskIntoConstraints = false
topImageContainerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
topImageContainerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
topImageContainerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
topImageContainerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
view.addSubview(loginSignup)
loginSignup.translatesAutoresizingMaskIntoConstraints = false
loginSignup.topAnchor.constraint(equalTo: view.topAnchor,constant:hgt/2).isActive = true
loginSignup.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
loginSignup.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
loginSignup.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
}
}
enter image description here
Here you need to add target and selector for when the x button is clicked
let backItem = UIBarButtonItem(title: "X ",
style: UIBarButtonItem.Style.done,
target: self, action:#selector(goBack))
#objc func goBack(_ bar:UIBarButtonItem) {
self.navigationController?.popToRootViewController(animated:true)
}

Buttons Programmatically on Swift 4

A quick question, I am trying to create a function called setupHeader() in which when called, setups up all the views and buttons of the header. The problem is with the Log Out button, for some reason I cannot get it right.
The first error is that the addTarget of the button doesn't recognize "self". Any suggestions?
The second one is that the #selector only works with the #objc func and the function cannot be in the main setupHeader function. Where should I put it? here is a snippet of my code:
import Foundation
import UIKit
func setupHeader(vc: UIViewController) {
let headerFiller: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = supaGray
return view
}()
let header: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = supaGray
return view
}()
let logOutButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Log Out", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.textAlignment = .left
button.addTarget(self, action: #selector(handleLogOutButton), for: .touchUpInside)
return button
}()
func handleLogOutButton() {
}
vc.view.addSubview(header)
header.topAnchor.constraint(equalTo: vc.view.safeAreaLayoutGuide.topAnchor).isActive = true
header.leftAnchor.constraint(equalTo: vc.view.leftAnchor).isActive = true
header.rightAnchor.constraint(equalTo: vc.view.rightAnchor).isActive = true
header.heightAnchor.constraint(equalToConstant: 40).isActive = true
header.addSubview(logOutButton)
logOutButton.centerYAnchor.constraint(equalTo: header.centerYAnchor, constant: -5).isActive = true
logOutButton.leftAnchor.constraint(equalTo: header.leftAnchor, constant: 7).isActive = true
logOutButton.widthAnchor.constraint(equalTo: header.widthAnchor, multiplier: 0.17).isActive = true
logOutButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
vc.view.addSubview(headerFiller)
headerFiller.topAnchor.constraint(equalTo: vc.view.topAnchor).isActive = true
headerFiller.leftAnchor.constraint(equalTo: vc.view.leftAnchor).isActive = true
headerFiller.rightAnchor.constraint(equalTo: vc.view.rightAnchor).isActive = true
headerFiller.bottomAnchor.constraint(equalTo: header.topAnchor).isActive = true
}
Declare your button press callback this way.
#objc func handleLogOutButton() {
}
And For self error use vc as your passing as argument above in function.
It looks like you're passing a view controller into your function so using self won't work. Try using 'vc'
Pretty straight forward:
Modify your code as shown below:
lazy var logOutButton: UIButton = {
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("Log Out", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.textAlignment = .left
button.addTarget(self, action: #selector(handleLogOutButton), for: .touchUpInside)
return button
}()
#objc func handleLogOutButton() {
// Do your things here
}

Why Doesn't Swift 3 recognize me button tap?

let playButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "VideoIcon.png") as UIImage?
button.backgroundImage(for: .normal)
button.addTarget(self, action: #selector(pressBackButton(button:)), for: .touchUpInside)
button.setImage(image, for: .normal)
return button
}()
func pressBackButton(button: UIButton) {
print("test")
if let playVideoButtonURL = post?.videourl {
let player = AVPlayer(url: playVideoButtonURL as URL)
let playerLayer = AVPlayerLayer(player:player)
playerLayer.frame = CGRect(x: 100, y: 200, width: 100, height: 100)
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
self.layer.addSublayer(playerLayer)
player.play()
}
}
even if the video code is wrong it should still print test but it doesn't which is strange. I feel like something may be wrong with the selector but i currently have no idea what could be wrong with it.
access function or property in self outside of initializer.
class TestViewController: UIViewController {
let playButton: UIButton = {
let button = UIButton()
let image = UIImage(named: "VideoIcon.png") as UIImage?
button.backgroundImage(for: .normal)
button.setImage(image, for: .normal)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(pressBackButton(button:)), for: .touchUpInside)
}
}
Instead of doing:
let playButton: UIButton = {
...
...
return button
}()
which won't work (because you're attempting to create playButton at the wrong time -- which is before the view is loaded or before it's about to appear)
In your viewDidLoad or viewWillAppear, create the button, define the target and simply add it as a subview.
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton()
if let image = UIImage(named: "VideoIcon.png") as UIImage?
{
button.backgroundImage(for: .normal)
button.addTarget(self, action: #selector(pressBackButton(button:)), for: .touchUpInside)
button.setImage(image, for: .normal)
}
self.addSubview(button)
}
Adding the button as a subview increments the retain count (i.e. it won't go away), but if you want to keep it around as a property simply declare it as:
var playButton : UIButton?
and then set playButton = button at the end of viewDidLoad.