Enable copy button title on long press on the button - swift

I have UIButton for an address in my tableview cell. When I tap on it once; I open google map with the direction no problem. Now, I want to provide the option for long gesture so if you hold your finger on the button, it provides the option to copy the address which is in the title of the button. This is my code:
#IBOutlet weak var addressBtn: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
addLongPressGesture()
}
#objc func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizer.State.began {
// how do I make it possible to copy the title of the button here? The address is already inserted as the title of the button
}
}
func addLongPressGesture(){
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
longPress.minimumPressDuration = 0.5
self.addressBtn.addGestureRecognizer(longPress)
}
This is where on one tap it goes to the map with no problem; so I have no issue here but just fyi:
#IBAction func addressClicked(_ sender: Any) {
if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")! as URL)) {
let street = order.street.replacingOccurrences(of: " ", with: "+")
let postalCode = order.postalCode.replacingOccurrences(of: " ", with: "+")
if street == "" || order.city == "" || order.province == "" || postalCode == ""{
UIApplication.shared.open(URL(string:"comgooglemaps://?saddr=&daddr=\(order.longitude),\(order.latitude)&directionsmode=driving")! as URL)
} else {
UIApplication.shared.open(URL(string:"comgooglemaps://?saddr=&daddr=+\(street),+\(order.city),+\(order.province),+\(postalCode)&directionsmode=driving")! as URL)
}
} else {
NSLog("Can't use comgooglemaps://")
}
}

Use
let text = addressBtn.currentTitle
or
let text = addressBtn.titleLabel?.text

I figured it out with the following code:
//Create the AlertController and add Its action like button in Actionsheet
let actionSheetControllerIOS8: UIAlertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
actionSheetControllerIOS8.view.tintColor = AppColors.Blue
let cancelActionButton = UIAlertAction(title: "Cancel", style: .cancel) { _ in
}
actionSheetControllerIOS8.addAction(cancelActionButton)
let saveActionButton = UIAlertAction(title: "Open Google Map", style: .default)
{ _ in
if (UIApplication.shared.canOpenURL(NSURL(string:"comgooglemaps://")! as URL)) {
let street = order.street.replacingOccurrences(of: " ", with: "+")
let postalCode = order.postalCode.replacingOccurrences(of: " ", with: "+")
if street == "" || order.city == "" || order.province == "" || postalCode == ""{
UIApplication.shared.open(URL(string:"comgooglemaps://?saddr=&daddr=\(order.longitude),\(order.latitude)&directionsmode=driving")! as URL)
} else {
UIApplication.shared.open(URL(string:"comgooglemaps://?saddr=&daddr=+\(street),+\(order.city),+\(order.province),+\(postalCode)&directionsmode=driving")! as URL)
}
} else {
NSLog("Can't use comgooglemaps://")
}
}
actionSheetControllerIOS8.addAction(saveActionButton)
let deleteActionButton = UIAlertAction(title: "Copy Address", style: .default)
{ _ in
let address = "\(order.street), \(order.city), \(order.province), \(order.postalCode)"
let pasteBoard = UIPasteboard.general
pasteBoard.string = address
}
actionSheetControllerIOS8.addAction(deleteActionButton)
self.present(actionSheetControllerIOS8, animated: true, completion: nil)
}

Related

How to limit character for username in Swift

i need to limit character for username in my swift code.
Username only can use those characters "abcdefghijklmnopqrstuvwxyz._1234567890".
Please forgive me if i'm noob, i don't have programming background. Still learning .
Below are swift code, which part i need to edit ?
// MARK: - SIGNUP BUTTON
#IBAction func signupButt(_ sender: AnyObject) {
dismissKeyboard()
// You acepted the TOS
if tosAccepted {
if usernameTxt.text == "" || passwordTxt.text == "" || emailTxt.text == "" || fullnameTxt.text == "" {
simpleAlert("You must fill all fields to sign up on \(APP_NAME)")
self.hideHUD()
} else {
showHUD("Please wait...")
let userForSignUp = PFUser()
userForSignUp.username = usernameTxt.text!.lowercased()
userForSignUp.password = passwordTxt.text
userForSignUp.email = emailTxt.text
userForSignUp[USER_FULLNAME] = fullnameTxt.text
userForSignUp[USER_IS_REPORTED] = false
let hasBlocked = [String]()
userForSignUp[USER_HAS_BLOCKED] = hasBlocked
// Save Avatar
let imageData = avatarImg.image!.jpegData(compressionQuality: 1.0)
let imageFile = PFFile(name:"avatar.jpg", data:imageData!)
userForSignUp[USER_AVATAR] = imageFile
userForSignUp.signUpInBackground { (succeeded, error) -> Void in
if error == nil {
self.hideHUD()
let alert = UIAlertController(title: APP_NAME,
message: "We have sent you an email that contains a link - you must click this link to verify your email and go back here to login.",
preferredStyle: .alert)
// Logout and Go back to Login screen
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
PFUser.logOutInBackground(block: { (error) in
self.dismiss(animated: false, completion: nil)
})
})
alert.addAction(ok)
self.present(alert, animated: true, completion: nil)
// ERROR
} else {
self.simpleAlert("\(error!.localizedDescription)")
self.hideHUD()
}}
}
You can use regex for this, check out the code below.
let usernameRegex = "^[a-zA-Z0-9]{4,10}$"
let usernameTest = NSPredicate(format:"SELF MATCHES %#", usernameRegex)
print(usernameTest.evaluate(with: "asAZ")) // boolen
You can even create an extension out of it like this
extension String {
func isValidUserName() -> Bool{
let usernameRegex = "^[a-zA-Z0-9]{4,10}$" // your regex
let usernameTest = NSPredicate(format:"SELF MATCHES %#", usernameRegex)
return usernameTest.evaluate(with: self)
}
}
use it like this
yourText.isValidUserName() // return true or false .
You can google any kind of regex to fit your case, and future ones, i even recommend saving those regex in an enum, and create a function that accept those enums and validate, look at this as a hint
enum ValidationRgex: String {
case username = "^[a-zA-Z0-9]{4,10}$"
}
extension String {
func isValid(_ regex: ValidationRgex) -> Bool{
let usernameRegex = regex.rawValue
let usernameTest = NSPredicate(format:"SELF MATCHES %#", usernameRegex)
return usernameTest.evaluate(with: self)
}
}
"MyText".isValid(.username) // usage

swift - cannot make my if statement work is well as i need

i have a problem when i typed my code as is bellow but i got error ?!
i want user if typed code = 4234 on textFields and tap on "ADD" = "https://pastebin.com/raw/4234"
else = any url "http://www.example.com/"
#IBAction func btnPlusPressed(_ sender: UIButton)
{
let alert = UIAlertController(title: "Provider M3U URL", message: "Add Provided URL to add you M3U Plailist", preferredStyle: .alert)
let loginAction = UIAlertAction(title: "ADD", style: .default, handler: { (action) -> Void in
var url = alert.textFields![0]
if (url.text == "535" as String ){
let strURLl : String = "https://pastebin.com/raw/\(url.text!)"
}else{
let strURLl : String = "\(url.text!)"
}
UserDefaults .standard .set(strURLl, forKey: "URL")
let channelsVC = self.storyboard!.instantiateViewController(withIdentifier: "ChannelsViewController") as! ChannelsViewController
channelsVC.strURL = strURLl!
self.navigationController?.pushViewController(channelsVC, animated: true)
})
why error appear like this : (Use of unresolved identifier 'strURLl')
Here you are defining the constant strURLl within the scope of the IF statement.
It means you cannot use it once outside of those { } around it
if (url.text == "535" as String ){
let strURLl : String = "https://pastebin.com/raw/\(url.text!)"
} else {
let strURLl : String = "\(url.text!)"
}
Same problem with the else statement.
Solution
Simply declare the constant outside of the IF scope
let strURLl: String
if (url.text == "535" as String ){
strURLl = "https://pastebin.com/raw/\(url.text!)"
} else {
strURLl = "\(url.text!)"
}

swift where shall i add tableview.reload to fetch data from first button click?

Below is my code to fetch images from icloudkit however now I have to click the UIbutton "getAlbum" 2 times for the images to be displayed in the table view. so did I add tableview.reload()m in a wrong place? please advise
#IBAction func getAlbum(_ sender: AnyObject) {
//Below line to dismiss the keyboard.
textEntercode.resignFirstResponder()
if (self.textEntercode.text == "")
{
let alert = UIAlertController(title: "No Code Entered", message: "Please enter photos code", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil));
//event handler with closure
present(alert, animated: true, completion: nil);
}
else //G
{
// let code: Int64 = Int64(self.textEntercode.text!)!
var photoCode = textEntercode.text!
// convert the characters to upper case before getting data from database
photoCode = photoCode.uppercased()
var count = 0
let Container = CKContainer.default()
let database = Container.publicCloudDatabase
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Photos", predicate: predicate) //Photos is table name in cloudkit server
//-------Fetch the data---------------------
database.perform(query, inZoneWith: nil) { //A
records, error in
if error != nil { //B
print(error?.localizedDescription ?? 10)
} // B
else { //C
count = (records?.count)!
print("countttttt \(count)")
for myrecord in records!
{ //D
self.Saveddata.append(myrecord as CKRecord)
//self.tableview.reloadData()
} //D
let Queue = OperationQueue.main
Queue.addOperation() { //E
self.tableview.reloadData()
} //E
} //C
} //A
} //G

Shows the Alert when UITextField's are full or empty Swift

Below is the code in that if the userNameTF or the passwordTF are full or empty it shows the alert.
#IBAction func LoginBtn(sender: AnyObject) {
let userName = userNameTF.text
let password = passwordTF.text
if ((userName?.isEmpty) != nil) {
displayMyAlertMessage ("Forget to fill your user name")
return
}
if ((password?.isEmpty) != nil){
displayMyAlertMessage ("Forget to fill your password")
return
}
}
func displayMyAlertMessage(userMessage:String){
let myAlert = UIAlertController(title: "WOF", message: userMessage, preferredStyle: UIAlertControllerStyle.Alert)
let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil)
myAlert.addAction(okAction)
self.presentViewController(myAlert, animated: true, completion: nil)
}
You can simply check your code with my code. there is minor mistake u did for checking value is empty or not.
follow below steps :
1.) Define IBOutlet for textfield
#IBOutlet var userNameTF : UITextField!
#IBOutlet var passwordTF : UITextField!
2.) Write below code on button clicked Event.
let userName = userNameTF.text
let password = passwordTF.text
if (userName!.isEmpty)
{
displayMyAlertMessage ("Forget to fill your user name")
return
}
else if (password!.isEmpty)
{
displayMyAlertMessage ("Forget to fill your password")
return
}
else
{
// Do Whatever u want.
}
Enjoy coding...its work fine.
That's a good example to use guard
#IBAction func LoginBtn(sender: AnyObject) {
guard let userName = userNameTF.text where !userName.isEmpty else {
displayMyAlertMessage ("Forget to fill your user name")
return
}
guard let password = passwordTF.text where !password.isEmpty else {
displayMyAlertMessage ("Forget to fill your password")
return
}
// do something with userName and password
}

How to put large chunk of code in AlertController block (Swift)

In my collection view cell, I have a button which successfully saves the current user (PFUser) to an array of users of each event (which are the objects at index path).
However, I would like to add an alert view, but have been unsuccessful in putting the enormous chunk of code inside the alert action block. I suppose I could create another method but I feel there's a simpler way to do it.
When I tried putting it in, A. the sheer number of brackets threw me off a bit and B. it didn't recognize "alertController" anymore at the bottom of the method.
Thanks for the help like always.
func buttonTapped(sender: AnyObject) {
let button = sender as! UIButton
let view = button.superview
let cell = view?.superview as! EventCell
let indexPath = collectionView.indexPathForCell(cell)
// print(indexPath)
if let indexPath = indexPath {
if let event = events?[indexPath.row] {
//pops alert vc
var alertController : UIAlertController = UIAlertController(title: event.eventTitle, message: nil, preferredStyle: UIAlertControllerStyle.Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
let saveUserToEvent = UIAlertAction(title: "Yes", style: .Default) { _ in
// WHAT TO DO HERE? I want to add the stuff below
}
alertController.addAction(saveUserToEvent)
var attendees = [String]()
if let attendeesTmp = event["attendees"] as?[String] {
attendees = attendeesTmp;
}
if let objId = PFUser.currentUser()?.objectId {
var found = false
for objIdd in attendees {
if objIdd == objId {
found = true
break;
}
}
if !found {
attendees.append(objId)
event["attendees"] = attendees;
event.saveInBackground()
}
}
if let user = PFUser.currentUser() {
var eventsAttending = [String]()
if let eventsAttendingTmp = user["eventsToAttend"] as?[String] {
eventsAttending = eventsAttendingTmp;
}
if let eventId = event.objectId {
var found = false
for eventIdd in eventsAttending {
if eventIdd == eventId {
found = true
break;
}
}
if !found {
eventsAttending.append(eventId)
user["eventsToAttend"] = eventsAttending;
user.saveInBackground()
}
}
}
}
}
}
Did you put
alertController.addAction(saveUserToEvent)
In the brackets as well? It stays outside.
This should work
func buttonTapped(sender: AnyObject) {
let button = sender as! UIButton
let view = button.superview
let cell = view?.superview as! UITableViewCell
let indexPath = collectionView.indexPathForCell(cell)
// print(indexPath)
if let indexPath = indexPath {
if let event = events?[indexPath.row] {
//pops alert vc
var alertController : UIAlertController = UIAlertController(title: event.eventTitle, message: nil, preferredStyle: UIAlertControllerStyle.Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
let saveUserToEvent = UIAlertAction(title: "Yes", style: .Default) { _ in
var attendees = [String]()
if let attendeesTmp = event["attendees"] as?[String] {
attendees = attendeesTmp;
}
if let objId = PFUser.currentUser()?.objectId {
var found = false
for objIdd in attendees {
if objIdd == objId {
found = true
break;
}
}
if !found {
attendees.append(objId)
event["attendees"] = attendees;
event.saveInBackground()
}
}
if let user = PFUser.currentUser() {
var eventsAttending = [String]()
if let eventsAttendingTmp = user["eventsToAttend"] as?[String] {
eventsAttending = eventsAttendingTmp;
}
if let eventId = event.objectId {
var found = false
for eventIdd in eventsAttending {
if eventIdd == eventId {
found = true
break;
}
}
if !found {
eventsAttending.append(eventId)
user["eventsToAttend"] = eventsAttending;
user.saveInBackground()
}
}
}
}
alertController.addAction(saveUserToEvent)
}
}
}