Position UIButton in UITextview - ios

I would like to place a "forgot?" Button into my Password Textfield. If nothing is in the Textfield the user should be able to click it and another ViewController should pop up. The only thing I managed to do is what you can see in the picture down below. My problem is that the button is not clickable and that it is not on the same level as the placeholder text. Any ideas on how to solve this two problems?
let button = UIButton(type: .custom)
button.setTitle("vergessen?", for: .normal)
button.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(100), height: CGFloat(100))
button.addTarget(self, action: #selector(self.refresh), for: .touchUpInside)
passwordTextField.rightView = button
passwordTextField.rightViewMode = .unlessEditing

In the file you have subclassed from my answer add another function in that file
// Modify the values as required
override func rightViewRect(forBounds bounds: CGRect) -> CGRect {
let offset = -20
let width = 100
let height = width
let x = Int(bounds.width) - width - offset
let y = offset
let rightViewBounds = CGRect(x: x, y: y, width: width, height: height)
return rightViewBounds
}
Now you can remove the follow line
button.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(100), height: CGFloat(100))
Output
And regarding the button click event. Remove your code as you mention its not connected
IBAction func refresh(_ sender: Any) { }
And add the following code in the same file where the button is created.
#objc func refresh() {
// your vc code here
print("in refresh")
}
The above code hooks in with addTarget code you have.
button.addTarget(self, action: #selector(self.refresh), for: .touchUpInside)
Hope this helps.

I suggest to create a xib file and its relevant view for text items that have a button inside it. So you would be able to reuse it elsewhere in the future (this or another projects)
By defining constant height (100) you will experience ugly and misplaced UI in different iOS devices.
Here it is what you should do :
Define a xib file for your custom UITextView
Create constraints for it so it width and height defined by its parent.Also define your forgot UIButton in relative to your UITextView.
Define its (xib) relevant UIView class
Use it in your Storyboard

You can use Storyboard. Make a helper view for the password TextField and Forgot Button.
-Set the Helper view same width and height with the email TextField.
-Add a TextField and a Button inside the helper view and then you can decide for the password TextField width and the Forgot Button width.
-Set constrains for the TextField and Button
I set green color to understand what the helper View does.
Update
I just used your code and it works fine.Check your textfield constrains again. This is what I used.
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type: .system)
button.setTitle("vergessen?", for: .normal)
button.setTitleColor(#colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1), for: .normal)
button.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(100), height: CGFloat(100))
button.addTarget(self, action: #selector(self.refresh), for: .touchUpInside)
textfFeld.rightView = button
textfFeld.rightViewMode = .unlessEditing
}
#objc func refresh(_ sender: Any) {
print("Hello")
}
The only think I changed is the button type from .custom to .system.

Related

tabbar middle tab out of tabbar corner

I want to make a tab bar with 5 tab items. I want the middle one ( third ) to be out of tab bar's corner it may be tough to understand therefore I decided to add screenshot
I want to make something like you can see above but I don't know how it's possible.
I would appreciate any way you recommend to do it.
select tabbar Item and set its image insets
Make sure to get proper image (if using an image) goto Assets-> select desired image -> set property to always original
create a class of UITabBarController and assign it to the TabBarController.
initialise Variable
let button = UIButton.init(type: .custom)
Then in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
button.setImage(UIImage(named: "IMAGE_NAME_FROM_ASSETS"), for: .normal)
button.backgroundColor = UIStyle.Color.CameraBG
button.layer.cornerRadius = 40
button.addShadow(offset: CGSize(width: 5, height: 5), color: UIStyle.Color.CameraShadow, radius: 5, opacity: 0.1)
button.addTarget(self, action: #selector(pressedAction(_:)), for: .touchUpInside)
self.view.insertSubview(button, aboveSubview: self.tabBar)
}
Add viewDidLayoutSubviews in your class
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// safe place to set the frame of button manually
button.frame = CGRect.init(x: self.tabBar.center.x - 40, y: self.view.bounds.height - 100, width: 80, height: 80)
}
Action You Want To Perform on button click
#objc func pressedAction(_ sender: UIButton) {
// do your stuff here
let nc = UINavigationController(rootViewController: YOURVC.storyboardInstance())
nc.modalPresentationStyle = .fullScreen
present(nc, animated: true, completion: nil)
}

Create UIButton on top layer UITableViewController like as AirBnB

How to create UIButton in UITableViewController like as AirBnB map.
Highlighted in red in screenshot.
It's quite easy actually, just create the table view as you always do (either storyboard or code) then create the button, position it correctly, set constraints and make sure it's not a subview of the table view but the view that contains the table view.
Since you didn't specify whether you use the storyboard or not, I did use it for the example below.
See this extremely simple demo I've just created:
This is the view hierarchy:
And these are the constraints for the button:
Create a button first and then then override the function scrollViewDidScroll():
import UIKit
class YourTableViewController: UITableViewController {
private let button = UIButton(type: UIButton.ButtonType.custom) as UIButton
override func viewDidLoad() {
let image = UIImage(named: "Image.png")
button.frame = CGRect(x: yourXpos, y: yourYPos, width: 60, height: 60)
button.setImage(image, for: .normal)
button.clipsToBounds = true
button.layer.cornerRadius = 30
button.addTarget(self, action: #selector(buttonClicked(_:)), for:.touchUpInside)
areaOfTableView.addSubview(button)
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = self.areaOfTableView.contentOffset.y
button.frame = CGRect(x: yourXpos, y: offset + yourYpos, width: btn.frame.size.width, height: btn.frame.size.height)
}
#objc private func buttonClicked(_ button: UIButton) {
// Action when you tapped the button
}
}

Fixing "use of unresolved identifier 'addTarget'" while adding func to button click event

I've created a UIButton programmatically as shown below:
let buttons: [UIButton] = [UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))];
Now if I try to add a function to it programmatically like this:
[buttons[0] addTarget:self action:#selector(buttonClicked:)forControlEvents:UIControlEventTouchUpInside]
I get an error saying that addTarget is not defined.
How do I fix this?
you are try to use the Objective-C syntax in swift, this is entirely wrong, use your code as like
buttons.first?.addTarget(self, action: #selector(self.buttonClicked(_:)), for: .touchUpInside)
and handle the action as like
#objc func buttonClicked( _ sender: UIButton) {
print("buttonClicked Action Found")
}
Ref : Apple Document for UIButton
First of all you are creating [UIButton] which is Array of UIButton and it's not a single Button.
You can not create Array of UIButton that way. You will need a for loop for that and you need to update the frame accordingly.
And you can create a single UIButton this way:
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
then you can add it into the UIView this way:
self.view.addSubview(button)
Without above line it your button will not show into your screen.
Next if you want to add action to that button you can do it by adding this line in your button code:
button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
and it will need a helper method which will execute when button will click.
#objc func buttonClicked(_ sender: UIButton) {
//Perform your action when button is clicked.
}
And you also need to apply backgroundColor and setTitle to the button.
and your final code will look like:
let button = UIButton(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
button.backgroundColor = UIColor.green
button.setTitle("Test Button", for: .normal)
button.addTarget(self, action: #selector(buttonClicked), for: .touchUpInside)
self.view.addSubview(button)

Swift Custom keyboard - show extra letters pop-up on keyboard long press?

I have a custom keyboard extension in my app which is developed using swift. They keyboard works fine. I wanted to add the functionality of showing a pop-up with extra characters when long-press on a keyboard button like the default iOS keyboard. Something like this:
I searched a lot, but most of them are un-answered and the answered ones are in Obj-C. I don't know much about Obj-C and am fairly new to swift programming also.
I have already looked at this, this and this. But these are not of much help.
Any help would be really appreciated.
1. Add Button on your View
(This is just to show you)
let btn: UIButton=UIButton(frame: CGRect(x: 5, y: 70, width: 30, height: 30))
btn.setTitle("A", for: .normal)
btn.setTitleColor(UIColor.black, for: .normal);
self.view.addSubview(btn)
2. Add Long PressGesture on your button
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPress(sender:)))
longGesture.minimumPressDuration = 1.2
btn.addGestureRecognizer(longGesture)
3. Handle Long press Gesture ,
You can Add PopUpView and add Some button on it ,
⚠️ Note: You have Multiple buttons so you have to check From CGPoint
on Which Button it was tapped on
func longPress( sender: Any) {
let longPressGesture = sender as! UILongPressGestureRecognizer
//Only run this code When State Begain
if longPressGesture.state != UIGestureRecognizerState.Began {
return
}
// if PopUpView is Already in added than remove and than add
if let checkView = self.view.viewWithTag(1001) as? UIView {
// remove popView
popUpView .removeFromSuperview()
}
let tapLocation = longPressGesture.location(in: self.view)
popUpView=UIView(frame: CGRect(x: tapLocation.x-10, y: tapLocation.y-65, width: 150, height: 60))
popUpView.backgroundColor=UIColor.orange
popUpView.layer.cornerRadius=5
popUpView.layer.borderWidth=2
popUpView.tag=1001
popUpView.layer.borderColor=UIColor.black.cgColor
let btn0: UIButton=UIButton(frame: CGRect(x: 5, y: 5, width: 30, height: 30))
btn0.setTitle("A1", for: .normal)
btn0.setTitleColor(UIColor.black, for: .normal);
btn0.layer.borderWidth=0.5
btn0.layer.borderColor=UIColor.lightGray.cgColor
popUpView.addSubview(btn0)
let btn1: UIButton=UIButton(frame: CGRect(x: 35, y: 5, width: 30, height: 30))
btn1.setTitle("A2", for: .normal)
btn1.setTitleColor(UIColor.black, for: .normal);
btn1.layer.borderWidth=0.5
btn1.layer.borderColor=UIColor.lightGray.cgColor
popUpView.addSubview(btn1)
let btn2: UIButton=UIButton(frame: CGRect(x: 70, y: 5, width: 30, height: 30))
btn2.setTitle("A2", for: .normal)
btn2.setTitleColor(UIColor.black, for: .normal);
btn2.layer.borderWidth=0.5
btn2.layer.borderColor=UIColor.lightGray.cgColor
popUpView.addSubview(btn2)
btn0.addTarget(self, action: #selector(self.buttonAction(sender:)),
for: UIControlEvents.touchUpInside)
btn1.addTarget(self, action: #selector(self.buttonAction(sender:)),
for: UIControlEvents.touchUpInside)
btn2.addTarget(self, action: #selector(self.buttonAction(sender:)),
for: UIControlEvents.touchUpInside)
self.view.addSubview(popUpView)
}
4. Handle The extra Button Press
(Do your Stuff here add remove popUpView from SuperView)
func buttonAction( sender: Any) {
// Do your Stuff Here
//Than remove popView
popUpView .removeFromSuperview()
}
Result ✅
✅ Note: You can Draw custom Shape of PopUpView Using UIBezierPath
You should use LongPress Recognizer. Please check this for more detail. Long press delete key of a custom keyboard in swift
This is very simple follow this step for achieve that task
Open your main story board
Select your TextField where you want multiple letter want's to show.
Open Attribute inspector from the right of your screen
Scroll it up and looks for capitalization just below of Min font size
Set capitalization as Words
Set all other Default and mainly keyboard type Now build and run that and check with letter s, e and etc.

Make the navigationbar title clickable swift

I would like to make the navigationbar title to be clickable. When user click on it, it should perform a segue. But I have no idea how to do this.
I have tried the following to get the title and apply the Tap gesture to it.
var subviews = self.navigationController?.navigationBar.subviews
if let subviews = subviews {
// Better check for array length before accessing to the 1st element
var subview = subviews [0]
}
but its giving me error Variable subview inferred to have type AvyObject, which may be unexpected
One more approach to add button as a title of navigation controller.
You need to set navigation item title view to your button object
Create button object in viewDidLoad() method:
Swift 4.0 Edit
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
button.backgroundColor = .red
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(clickOnButton), for: .touchUpInside)
navigationItem.titleView = button
Here you can see in last line button is directly set to the titleView of navigationItem which will add button at the center of navigation bar.
Action method for button is below:
#objc func clickOnButton() {
}
Kampai's answer updated for Swift 3:
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(self.clickOnButton), for: .touchUpInside)
self.navigationItem.titleView = button
To get rid of that error, specify a type for your if let constant. I'd also recommend changing that if let constant name since it's the same as the one already declared in the previous line.
var subviews = self.navigationController?.navigationBar.subviews
if let subviewArray:NSArray = subviews {
// Better check for array length before accessing to the 1st element
var subview:UILabel = subviewArray[0] // <-- If the subview's a UILabel
}

Resources