UIButton text not updating - ios

A "tried and true" pattern I've used in my iOS Swift app is that I have several areas with UIButtons. When the button is pressed, it fires off some net code that connects to my API. While this is happening, I have the button text say "please wait, loading" and I disable the button. When the queued action finishes in my callback I have the button text enable and change back to the original state. It works great.
I recently added something not using NSURL/NSDATA (it's just a file writer). I copied all the same GCD queue code and oddly enough it doesn't update the button text.
Here is my code. When you tap the button, the text becomes invisible until the callback finishes, and then it just restores back. Oddly enough if I change my simulator to iPad Pro it actually works (??) and says "please wait, downloading". If I switch to iPhone 6s it doesn't work.
#IBAction func btnGenerateCSV(sender: UIButton) {
//Grab the original text of the button to restore later after done
let originalButtonText = sender.titleForState(UIControlState.Normal)
//Localized is an extension function I wrote.
//As you can see I got crazy here adding all the UI States as a last ditch attempt to see if that was the reason.
sender.setTitle(Localized("Downloading"), forState: UIControlState.Normal)
sender.setTitle(Localized("Downloading"), forState: UIControlState.Disabled)
sender.setTitle(Localized("Downloading"), forState: UIControlState.Highlighted)
//I've tried moving this before the setTitle. No avail.
sender.enabled = false
//I've tried the other queues as well, and even just tried dispatch_async(dispatch_get_main_queue()) but no luck
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) { [unowned self] in
CsvReportWriter.GenerateReport()
{
r in
dispatch_async(dispatch_get_main_queue()) {
FileManager.WriteToFile(r, filename: self.filename)
if FileManager.FileExists(self.filename) {
self.docController = UIDocumentInteractionController(URL: FileManager.GetURLOfFile(self.filename))
self.docController.presentOptionsMenuFromRect(sender.frame, inView:self.view, animated:true)
}
//Restore button state and text b/c we're done
sender.enabled = true
sender.setTitle(originalButtonText, forState: UIControlState.Normal)
}
}
}
}
Any ideas? If I swap out the CsvReportWriter.GenerateReport() code with some other async code that does a call out to my API, it works.
Thanks so much!

So I wanted to post an answer that I thought was interesting - I had a different account logged in to my iPad Pro simulator.. and noticed that the label correctly appeared. In iPhone 6 it did not. I was logged into a different account.
So what was the difference? There were about 1,000,000 test rows to generate in the iPad pro, and 3 in the iPhone, so everything finished so fast there was no UI to even update.
I introduced a delay just as a test, and noticed that in fact it works / exports so that's actually what it was.
So it turns out things were running so fast there wasn't even time to update to 'please wait' lol
Sorry to bother anyone but feel free to use the above code as it should be effective to do what you need :)

Related

refundRequestSheet done button is not working properly [SwiftUI 4, iOS16.1+]

I am having an issue with refundRequestSheet. So basically, my issue is that everything is presented just fine, I can get through the refund process, but at the end of the process where we are having done button, after I press the done button nothing is happening, result is not being called - it looks like the button is not actually calling any action.
The only way for me to close the screen is to actually swipe the sheet down, and then the result of onDismiss sometimes is failure and sometimes is a success.
I also investigated other type of sheets such manageSubscriptionsSheet, and this is having the same issue basically.
I also tried both simulator and the actual device, still nothing.
.refundRequestSheet(for: viewModel.transactionID ?? 0, isPresented: $viewModel.showRefundSheet, onDismiss: { _ in
viewModel.showRefundSheet = false
})

Confusing button-actions in SwiftUI

Here is some SwiftUI code in a running app I am working on:
Button(action: action) {
Image(systemName: img)
.imageScale(.large)
}
.simultaneousGesture(LongPressGesture().onEnded { _in
playLngPress = true
showingFlag = true
})
My question is about the relationship between the chunk of code executed when making a long-press on the button and the chunk of code executed when making a simple tap. I first noticed that when making a long-press, the action (for a simple tap) was also executed along side.
Though I do not think this is how it should be, I made a work-around to have things go my way.
More recently (after moving to iOS 15, though I am not 100% sure this is the Reason) I noticed that the action for the tap is not always performed when making a long-press.
Can anyone precisely explain how this is working ?

Swift performSegueWithIdentifier delay

I have the following situation: I do a check when user touches screen, to check if it matches some bounds if menuButton.frame.contains(coordinates) {
Then, I try to push a segue like this performSegueWithIdentifier(menuButton.whichButton(menuButton.tag), sender: self) My problem is that the first time the segue performs, it has a huge delay (about 3-4 sec). Afterwards, everything runs as it should. I did check for main thread and I am in the main thread. Can you please help me?
I found the answer, as strange as it may appear, it was related with the fonts. I added some fonts, selected them in interface builder, but of course I didn't check the target membership. So the system was looking for them, I think, before reverting to default font, thus creating the lag. I hope it helps someone at some point.
Have you tried to run on a device or only in the simulator? Just to make sure...
You can try this too:
dispatch_async(dispatch_get_main_queue(),{
self.performSegueWithIdentifier(mysegueIdentifier, self)
})

Screenshotting on Iphone in swift only has a white background

Some background: I am just trying to do a simple program using xcode 6 beta 7 in swift to screenshot the iphone after I press a button. It is done in SpiteKit and in the game scene. The background is a random png image and the "hello world" default sample text. I programmatically put a press-able button (the default spaceship image is the button) in gamescene didMoveToView function using the following code:
button.setScale(0.2)
screen.frame = CGRect(origin: CGPointMake(self.size.width/4, self.size.height/1.5), size: button.size)
screen.setImage(playAgainButton, forState: UIControlState.Normal)
screen.addTarget(self, action: "action:", forControlEvents: UIControlEvents.TouchUpInside)
self.view!.addSubview(screen)
This sets my press-able button on the screen where it is linked to a function to take a screenshot using this next code:
func action(sender:UIButton!){
UIGraphicsBeginImageContext(self.view!.bounds.size)
self.view!.layer.renderInContext(UIGraphicsGetCurrentContext())
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}
So this code does take a screenshot, but when I look in photos, only the press-able button is shown and the rest of the image is white. The image is shown below:
Below, I think the screen shot should look like this as this is what the screen looks like in the simulator (I just used some random images/text as background):
Can someone explain to me why the screenshot program is not also taking a picture of the background and how to fix it?
I've looked online and I have not seen any question that is a solution to my problem. Online I saw some similar problems and tried out their fixes: I imported quartzCore, coreGraphics, and coreImages, but with no fix. Also, I tried using the ViewController and setting a UIbutton on there with a IBaction to screen shot, but still get the same white background image. I've tried different background images with the same result.
I am fairly new to programming so, any help would be appreciated! Thank you in advance!
Have you set the background as pattern-background-color? => Maybe this doesn't work as expected with renderInContext.
Is the background image rendered in self.view, either as a subview or in its drawRect: method? => if not, of course it will not be rendered.
The easiest way to get a screenshot is with the function
UIImage *_UICreateScreenUIImage();
you have to declare it first, because its an undocumented function. I'm not sure if Apple will accept an app that contains a call to this function, but I think it will be okay (I know the review guidelines say you must not use undocumented functions, but I think they will not care in this case.) It's available and working in iOS 5 - iOS 8 (i have tested it. don't care about iOS 4.)
Another thing that should also work is to render the whole screen instead of just one particular view:
UIGraphicsBeginImageContext(self.view!.window!.bounds.size)
self.view!.window!.layer.renderInContext(UIGraphicsGetCurrentContext())
let screenshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
(note that I replaced view! with view!.window! to get the one and only window instance.)

Possible UISwitch bug in iOS7?

I am using a UISwitch to call a subview to screen in my app. However, the switch only works about 60% of the time. To test my code I hooked the switch to another IBAction to write the state of the switch to the console. Both functions are not responding to the state of the switch at certain times, i.e., both functions are ignoring the state of the switch simultaneously some of the time. Has anybody else experienced this behaviour with UISwitches in iOS7?
- (IBAction)showHideSomeSubView:(UISwitch *)sender {
if (_mySwitch.on) {
[self.view addSubview:someSubView];
}
else {
[someSubVew removeFromSuperview];
}}
Edit:
The same switch is connected to the following action:
- (IBAction)switchToggled:(UISwitch *)sender {
sender = _mySwitch;
if ([sender isOn]) {
NSLog(#"On");
} else {
NSLog(#"Off");
}}
Both actions respond in the same way to the switch.
I confirm that weird behaviour with you!!!!
Just drag the little circle of the switch around and around, you will see the action called multiple times (in my case up to 403 :D )
I am really not sure that is what Apple engineers intended to do, because I have not found any documentation about this new behaviour, BTW, if you find one, please let me know too.
Thank you very much
I'm using several UISwitches in an iOS 7 app, I have had no problem at all responding to the Value Changed action. The switch consistently reports its value correctly. You should unhook the switch from its action in IB and then reconnect, making sure you are connecting the Value Changed action.
Yes, with a UISwitch in the iOS 7 iPad simulator, I am seeing 1-12 callbacks to my equivalent of your switchToggled: method. On the last callback, the value has in fact changed. On the previous callbacks, it hasn't. What I am doing is caching whether or not the switch is on. Then in the switchToggled: method, I check whether or not the value has in fact changed. If it hasn't, I ignore the callback. This seems to make things behave correctly for the user.
The problem does also happen on the device, though apparently less often. The same work-around seems to work there.

Resources