Swift 5 UIButton with image causing my apps freezing after open url - ios

I have an application that needs to open third-party apps (i.e Whatsapp), it runs smoothly when I build this app using Xcode 10, but in Xcode 12, it's causing the freeze. Does anyone have to face this problem before?
My code was like this
declaring button
let buttonWA: UIButton = {
let v = UIButton()
v.imageView?.contentMode = .scaleAspectFit
v.setImage(UIImage(named: "ic_whatsapp"), for: .normal)
return v
}()
let buttonEmail: UIButton = {
let v = UIButton()
v.imageView?.contentMode = .scaleAspectFit
v.setImage(UIImage(named: "ic_email"), for: .normal)
return v
}()
Then I add some functions to be called each button
#objc func WaPressed() {
let no = "*************".urlwithPercentEscapes()
let urlWhatsApp = "whatsapp://send?phone=\(no)"
self.openUrl(urlString: urlWhatsApp)
}
#objc func EmailPressed() {
self.openUrl(urlString: "mailto:myEmail#gmail.com")
}
func openUrl(urlString: String) {
guard let url = URL(string: urlString) else {
return
}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}
Everything running smoothly, and open third apps very well, but when I returning back to my apps, it goes freeze without telling me anything
I've tried change ".normal" options to other options like ".application" etc in the line
v.setImage(UIImage(named: "ic_whatsapp"), for: .normal)
and it makes my apps running well again, but I need this "for: .normal" state so bad.
Then I've tried to change
v.setImage(UIImage(named: "ic_whatsapp"), for: .normal)
to
v.setBackgroundImage(UIImage(named: "ic_whatsapp"), for: .normal)
and it works, but then the image scale is messy.
Could anybody help me to solve this?

After trying other options, I figure it out with add RenderingMode when I set Image in my button, the code looks like this:
For whatsapp button
v.setImage(UIImage(named: "ic_whatsapp").withRenderingMode(.alwaysOriginal), for: .normal)
For email button
v.setImage(UIImage(named: "ic_email").withRenderingMode(.automatic), for: .normal)
I don't understand why I can't set "automatic / alwaysOriginal" both. But this way works for me.
Thankyou

Related

Swift - open URL from button click

I am learning Swift and iOS development, and I am just trying to figure out how to open an URL from a button click.
I found this answer: SwiftUI: How do I make a button open a URL in safari?
So I am trying to incorporate "Link" into my code below:
class ViewController: UIViewController {
private let visitwebsitebutton: UIButton = {
let visitwebsitebutton = UIButton()
visitwebsitebutton.backgroundColor = .gray
visitwebsitebutton.setTitle("Visit Website", for: .normal)
visitwebsitebutton.setTitleColor(.white, for: .normal)
visitwebsitebutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
visitwebsitebutton.layer.cornerRadius = 20
visitwebsitebutton.Link("Some label", destination: URL(string: "https://www.mylink.com")!) // <-- link used here
return visitwebsitebutton
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(visitwebsitebutton)
}
}
Using Link above gives me an error that reads "Value of type 'UIButton' has no member 'Link'".
What am I doing wrong and how can I fix it?
Edit 1
I just tried this inside private let visitwebsitebutton:
visitwebsitebutton(action: {"www.redacted.com"})
But now I'm getting the below error:
Cannot call value of non-function type 'UIButton'
Edit 2
Within private let visitwebsitebutton, I attempted the following:
visitwebsitebutton.addTarget(self, action: "buttonClicked", for: UIControl.Event.touchUpInside)
Using the above, I am getting a few warning:
'self' refers to the method 'ViewController.self', which may be unexpected
Use 'ViewController.self' to silence this warning
No method declared with Objective-C selector 'buttonClicked'
Replace '"buttonClicked"' with 'Selector("buttonClicked")'
I tried to call the buttonClicked like this:
#objc func buttonClicked(sender:UIButton)
{
if(sender.tag == 5){
var abc = "argOne" //Do something for tag 5
}
print("hello")
}
And above, I am getting the below warning:
Initialization of variable 'abc' was never used; consider replacing with assignment to '_' or removing it
Replace 'var abc' with '_'
I just want to get the button to work.
This is how I solved the problem:
class ViewController: UIViewController {
private lazy var visitwebsitebutton: UIButton = {
let visitwebsitebutton = UIButton()
let mygreen = UIColor(rgb: 0x12823b)
visitwebsitebutton.backgroundColor = mygreen
visitwebsitebutton.setTitle("Visit Website", for: .normal)
visitwebsitebutton.setTitleColor(.white, for: .normal)
visitwebsitebutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
visitwebsitebutton.layer.cornerRadius = 20
visitwebsitebutton.addTarget(self, action: #selector(visitwebsitebuttonTapped), for: .touchUpInside)
return visitwebsitebutton
}()
#objc func visitwebsitebuttonTapped() {
if let yourURL = URL(string: "https://www.somesite.com") {
UIApplication.shared.open(yourURL, options: [:], completionHandler: nil)
}
}
}
If anyone needs help with iOS mobile development with Swift, and you just want to be able to click on a button and have it take you to a site, look no further.

UIButton click function opens URL in blank screen

I am learning iOS and Swift development, and I was able to get a button click to open a URL.
Within Xcode, I am running the app by clicking the play button.
When the app opens, and I click the button on the app, it takes me to the URL.
The problem is: the screen is blank.
The address bar does show the URL.
Here is a portion of the code that I wrote that opens the URL:
class ViewController: UIViewController {
private lazy var visitwebsitebutton: UIButton = {
let visitwebsitebutton = UIButton()
let dtgreen = UIColor(rgb: 0x12823b)
visitwebsitebutton.backgroundColor = .green
visitwebsitebutton.setTitle("Visit Website", for: .normal)
visitwebsitebutton.setTitleColor(.white, for: .normal)
visitwebsitebutton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
visitwebsitebutton.layer.cornerRadius = 20
visitwebsitebutton.addTarget(self, action: #selector(visitwebsitebuttonTapped), for: .touchUpInside)
return visitwebsitebutton
}()
#objc func visitwebsitebuttonTapped() {
if let yourURL = URL(string: "https://www.somesite.com") {
UIApplication.shared.open(yourURL, options: [:], completionHandler: nil)
}
}
}
Using the above will successfully allow the user (which is me at the moment) to click on the button, and open the URL in another window on the Xcode emulator. But the screen is blank.
My question is: does this blank screen only occur when running the app in Xcode? Will it work properly when I publish this app to the web?

Stripe / Apple-pay Icon presented wrongly/ rejected by apple store

Apple rejected my app because Stripe pod show inappropriate apple pay icon, which added an extra "apple pay" next to the apple pay icon. (see attached)
Is anyone had the same problem like me and what are your solution?
Is anyone had successfully uploaded an app with apple pay function installed?
Please See my calling code as below too, many thank!
private func reloadPaymentButtonContent() {
guard let selectedPaymentMethod = paymentContext.selectedPaymentOption else {
// Show default image, text, and color
paymentButton.setImage(#imageLiteral(resourceName: "Payment"), for: .normal)
paymentButton.setTitle("付款", for: .normal)
paymentButton.setTitleColor(.gray, for: .normal)
return
}
// Show selected payment method image, label, and darker color
paymentButton.setImage(selectedPaymentMethod.image, for: .normal)
paymentButton.setTitle(selectedPaymentMethod.label, for: .normal)
paymentButton.setTitleColor(.blue, for: .normal)
}
private func reloadBuyButton(){
if paymentContext.selectedPaymentOption == nil {
// buySubscriptionButton.backgroundColor = .loopGrayColor
// buySubscriptionButton.setTitle("订阅", for: .normal)
// buySubscriptionButton.setTitleColor(.white, for: .normal)
buySubscriptionButton.isEnabled = false
}else{
buySubscriptionButton.isEnabled = true
// buySubscriptionButton.backgroundColor = .loopGreenColor
// buySubscriptionButton.setTitle("订阅", for: .normal)
// buySubscriptionButton.setTitleColor(.white, for: .normal)
}
You're setting both in the code. So, either set Image or Label text.

How can I change a group of button's image's colors in Swift3?

I recently asked a question here where I wanted to understand how to change the UIColor of a button's image. I followed #Dorian Roy's recommendation which was very clean and it worked well for my needs. While my specific question previously was around a single button, I would like to know how to change multiple UIBUttons. Can this be done? My thought would be to subclass a UIButton and initialize it to automatically change its image color. I can't quite grasp how to do this though.
Here is how I am currently performing this action and I am seeking a more elegant solution.
private func changeBtnColors() {
let ccStencil = creditCardBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let planeStencil = planeBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let towelStencil = towelBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let carStencil = carBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let trainStencil = trainBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let graphStencil = graphBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
creditCardBtn.setImage(ccStencil, for: .normal)
planeBtn.setImage(planeStencil, for: .normal)
towelBtn.setImage(towelStencil, for: .normal)
carBtn.setImage(carStencil, for: .normal)
trainBtn.setImage(trainStencil, for: .normal)
graphBtn.setImage(graphStencil, for: .normal)
creditCardBtn.tintColor = UIColor.white
planeBtn.tintColor = UIColor.white
towelBtn.tintColor = UIColor.white
carBtn.tintColor = UIColor.white
trainBtn.tintColor = UIColor.white
graphBtn.tintColor = UIColor.white
}
The simplest way is create one array of UIButton and loop through all the elements.
let buttonArray = [creditCardBtn, planeBtn, towelBtn, carBtn, trainBtn, graphBtn]
buttonArray.forEach { button in
let image = button.imageView?.image?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.white
}
You can also create extension of UIButton and put this settings code of Button in a function like this.
extension UIButton {
func setImageWithRandringMode() {
let image = self.imageView?.image?.withRenderingMode(.alwaysTemplate)
self.setImage(image, for: .normal)
self.tintColor = .white
}
}
And now simply call this function with forEach closure.
buttonArray.forEach { button in
button.setImageWithRandringMode()
}

Can't change UIbutton image for different state

I want to change the image of a UIButton for different states. To achieve this, I'm using:
btn.setImage(UIImage(named: "blabla"), for .normal)
and
btn.setImage(UIImage(named: blabla2), for .disabled)
This only makes some appear dimmed.
What did I do wrong? I just want to make my button appearance the same for different states, how?
(my button type - .system).
This helped me (swift 3.0)
btn.setImage(UIImage(named:"yourFriend")?.withRenderingMode(.alwaysOriginal), for: .normal)
btn.setImage(UIImage(named:"yourFriend")?.withRenderingMode(.alwaysOriginal), for: .disabled)
You just need to set one for the state. And if you don't set another image for different state. It would look the same in all state.
button.setImage(image, forState: .Normal)
How to change UIButton image in Swift
For display disabled button set image
let btn = UIButton(type: .Custom)
btn.setImage(UIImage(named: blabla2), for .disabled)
Then
btn.enabled = false // to display Disable image
btn.enabled = true // to display Normal image
private let button1: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named:"firstButtonNormalStateImage"), for: .normal)
button.setImagesetImage(UIImage(named:"firstButtonSelectedStateImage"), for: .selected)
return button
}()
private let button2: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named:"secondButtonNormalStateImage"), for: .normal)
button.setImage(UIImage(named:"secondButtonSelectedStateImage"), for: .selected)
return button
}()
// implement for example in viewDidLoad()
button1.addTarget(self, action: #selector(firstButtonDidTap), for: .touchUpInside)
button2.addTarget(self, action: #selector(secondButtonDidTap), for: .touchUpInside)
// trigger actions
#objc func firstButtonDidTap() {
button1.isSelected = true
button2.isSelected = false
}
#objc func secondButtonDidTap() {
button2.isSelected = true
button1.isSelected = false
}
For whoever is still having this issue (currently Xcode 10.0) with a Custom button, I found I was able to change the text and/or image if instead of:
myButton.setTitle("Hi", for: [.normal])
I used this:
myButton.setTitle("Hi", for: []) //remove specific states
I don't know why .normal was not working for me, even though the button was definitely enabled. But maybe this will save someone else a headache!
You can simply do this by StoryBoard as well.
Select the button, got to identity inspector and do the following:-
Firstly set the buttonType to custom instead of system.
Secondly choose state Config to lets say default and give the imageName in "image" attribute, similarly choose other state configs (Highlighted, disabled, selected etc.) and set images as required by you.
Then later in the code you just have to control and set the state of the button, and respective image will be shown to you.

Resources