#selector(didTapRegister) not in scope - swift

When I run this code by #selector(didTapRegister) I get a didTapRegister is not in scope. I have a bigger application I am using it in and on one page it works and another it won't, well it won't work anywhere else.
I am stuck on figuring out why. Can anyone help solve it? seems to be an Objective-C issue possibly because I have same issues trying to make IBOutlets, I have tried searching for answers and I just don't have enough knowledge to understand why it isn't working, I've tried moving the code to different scopes and still nothing. with the IBOutlets it's saying IBOutlet property cannot have non-object type UIButton?.Type
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let Button = UIButton.init(type: .custom)
Button.setTitle("Chat", for: .normal)
Button.layer.backgroundColor = CGColor.init(gray: 0.0, alpha: 0.0)
Button.setTitleColor(.white, for: .normal)
Button.setTitleColor(.red, for: .highlighted)
Button.layer.borderWidth = 1
Button.layer.cornerRadius = 5
Button.layer.borderColor = UIColor.white.cgColor
Button.isHighlighted = false
Button.showsTouchWhenHighlighted = true
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: Button)
Button.addTarget(self, action: #selector(didTapRegister), for: .touchUpInside)
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Do any additional setup after loading the view.
}
}
}

Maybe try what he said but
Just use SwiftUI it is much better
#objc and all of that is fine but in SwiftUI you can just right click and add buttons

There 2 mistakes in the code.
You have to create #objc function for the button action
In your code move viewWillAppear method outside the viewDidLoad
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton.init(type: .custom)
button.setTitle("Chat", for: .normal)
button.setTitleColor(.white, for: .normal)
button.setTitleColor(.red, for: .highlighted)
button.layer.borderWidth = 1
button.layer.cornerRadius = 5
button.layer.borderColor = UIColor.white.cgColor
button.isHighlighted = false
button.showsTouchWhenHighlighted = true
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)
button.addTarget(self, action: #selector(didTapRegister), for: .touchUpInside)
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
}
#objc func didTapRegister(_ sender: UIButton) {
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Do any additional setup after loading the view.
}
}
Note: button name start with lowercase.

Related

Make the UIRefreshControl short for swiping

When using the standard UIRefreshControl in TableView the swipe down can be too long, that is, I have to drag my finger almost to the very bottom of the screen.
Is it possible to shorten the swipe path?
var refreshControl = UIRefreshControl()
#objc func refresh(_ sender: AnyObject) {
// Refresh anything
}
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
refreshControl.backgroundColor = UIColor.clear
TableView.addSubview(refreshControl)
refresh(view)
}
Thank you in advance for your help.
Try it.
refreshControl.addTarget(self, action: #selector(refreshHande(_:)), for: .valueChanged)
let ori = tableView.frame
let temp_frame = CGRect.init(x: ori.origin.x, y: ori.origin.y, width:
ori.size.width, height: ori.size.height/1.3 )
tableView.frame = temp_frame
tableView.addSubview(refreshControl)
tableView.frame = ori
TableView has property refreshControl. Use the following code
var refreshControl = UIRefreshControl()
#objc func refresh(_ sender: AnyObject) {
// Refresh anything
}
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
refreshControl.backgroundColor = UIColor.clear
// tableView is a UITableView outlet
tableView.refreshControl = refreshControl
}

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?")
}

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)
}

Swift 3 - Floating Button over UICollectionView

I created a floating button by this first answer. It works but when the UICollectionViewlaunched, the floating button still square and became circle after all datas appear (after loadAPI finished running).
Here's my code:
override func viewDidLoad() {
super.viewDidLoad()
self.roundButton = UIButton(type: .custom)
self.roundButton.setTitleColor(UIColor.orange, for: .normal)
self.roundButton.addTarget(self, action: #selector(self.ButtonClick(_:)), for: UIControlEvents.touchUpInside)
self.view.addSubview(self.roundButton)
self.loadAPI(Page: 1)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
roundButton.layer.cornerRadius = roundButton.layer.frame.size.width/2
roundButton.backgroundColor = green
roundButton.clipsToBounds = true
roundButton.setImage(UIImage(named:"ic_add_white_2x"), for: .normal)
roundButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
roundButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
roundButton.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -20),
roundButton.widthAnchor.constraint(equalToConstant: 60),
roundButton.heightAnchor.constraint(equalToConstant: 60)
])
}
#IBAction func ButtonClick(_ sender: UIButton){
//print("clicked")
}
I need the button being a circle since the UICollectionView first appears. Can somebody help me please? Thanks!
// update this code
override func viewDidLoad() {
super.viewDidLoad()
self.roundButton = UIButton(type: .custom)
self.roundButton.setTitleColor(UIColor.orange, for: .normal)
self.roundButton.layer.cornerRadius = roundButton.layer.frame.size.width/2
self.roundButton.addTarget(self, action: #selector(self.ButtonClick(_:)), for: UIControlEvents.touchUpInside)
self.view.addSubview(self.roundButton)
self.loadAPI(Page: 1)
}

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.