Coincidentally, I encountered some strange behavior from my source code while developing an app:
I have started an interval that calls a function to output the set volume of the device.
When testing the code on a real device (iPhone X), I noticed that the "value of the volume does not seem to change" when I press one of the volume buttons.
This was the code I was using:
Timer.scheduledTimer(
timeInterval: 0.5,
target: self,
selector: #selector(self.getSystemVolume),
userInfo: nil,
repeats: true)
#objc func getSystemVolume() {
let outputVolume = AVAudioSession.sharedInstance().outputVolume
print(outputVolume)
}
Note: I'm not sure if this is a bug or not - could be!
However: Does anyone now how to fix behavior? Any help would be very appreciated :)
Looks like I've found a working solution on my own:
I've added those lines:
let volumeView = MPVolumeView()
volumeView.setNeedsLayout()
I got no idea why these lines cause the code to work, but however - now it's working.
#objc func getSystemVolume() {
let volumeView = MPVolumeView()
volumeView.setNeedsLayout()
let outputVolume = AVAudioSession.sharedInstance().outputVolume
print(outputVolume)
}
I really hope somebody could add a comment why these lines fix the code. :)
Related
let me explain you whole scenario:
I'm making the audio record & audio player
When I started recording audio.And I starts to click on pause and stop button multiple times like crazy kid and sometimes buttons stop working and got that error.
please help me out if anyone faces that issue once or resolve it
thanks in advance
In general, you could prevent the user from pressing a button repeatedly or too fast by disabling the button for a short period of time every time the button is pressed.
For example, disable the button for 2 seconds:
func pressButton() {
button.isEnabled = false
Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(enableButton), userInfo: nil, repeats: false)
}
#objc func enableButton() {
self.buttonTest.isEnabled = true
}
Turns out that the way I was adding my views inside th view was the main cause of the issue. My apologies!
I need help because i can't find example to do exactly what I want need anywhere.
I want to animate a simple png sequence, then call a performSegue once it's completed (that's my main problem)
So I tried with
InitImage.animationImages = [
UIImage(named:"load1.png")!,
UIImage(named:"load2.png")!,
UIImage(named:"load3.png")!,
/* 20 more images... */
]
InitImage.animationDuration = 2.5
InitImage.animationRepeattCount = 1
InitImate.startAnimating()
so it animates but call the segue too soon. I found that i should probably use
UIView.animate(withDuration : ...)
But I can't find an example written in Swift3 that animates a sequence of files.
Could someone show me the way?
thanks.
The simplest way I think is to make a timer
Timer.scheduledTimer(timeInterval: InitImage.animationDuration * Double(InitImage.animationImages?.count ?? 0), target: self, selector: #selector(push), userInfo: nil, repeats: false)
and selector
func push() {
.... perform segue
}
The simplest option is to use performSelector with afterDelay, since the self is an #objc UIViewController:
self.perform(#selector(segueToDetailViewController), with: self, afterDelay: InitImage.animationDuration)
And selector:
func segueToDetailViewController() {
self.performSegue( ... etc ... )
}
The code above is not multiplying the animation duration by the number of images because when I ran the code, I found that the animation duration for all images was 2.5 seconds.
I am using Here Maps SDK in my project in Swift 3 (in Xcode 8 for iOS 10) to grab the currentPosition from NMAPositioningManager. However, while isActive is true for the NMAPositioningManager, the currentPosition is always nil. I have a valid position and valid credentials H(ERE_MAPS_APPID, HERE_MAPS_APP_CODE, and HERE_MAPS_LICENSE_KEY).
I checked the SDKDemo with Xcode 8 for iOS 10, which runs fine, but their code is in Objective-C. Any comment would be appreciated.
if let posMan : NMAPositioningManager = NMAPositioningManager.shared() {
if let currPos = posMan.currentPosition{
if let geoCoordCenter = currPos.coordinates {
self.mapView.setGeoCenter(geoCoordCenter, with: NMAMapAnimation.none)
}
}
}
Make sure positioning is started (I guess you did, but it's not shown in your snipped, so pasting it here again for reference):
NMAPositioningManager.shared().startPositioning()
Then normally it takes some time till your position is available, so you can't query dirctly PositionManager. I suggest to register for the position update callbacks:
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.positionDidUpdate), name: NSNotification.Name.NMAPositioningManagerDidUpdatePosition, object: NMAPositioningManager.shared())
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.didLosePosition), name: NSNotification.Name.NMAPositioningManagerDidLosePosition, object: NMAPositioningManager.shared())
Then do in the callback with the position whatever you want:
func positionDidUpdate(){
if let p = NMAPositioningManager.shared().currentPosition {
mapView.setGeoCenter(p.coordinates, with: NMAMapAnimation.bow)
}
}
func didLosePosition(){
print("Position lost")
}
Let me know if it's still not working for you like this, and I'll add more complete code.
I am trying to build a simple single view app which runs an infinite slide show of a selection of images with a time delay between each image change.
The code I wrote for this is below. I tried to put this into viewDidLoad and viewDidAppear but the screen remained blank which I guess is because the function never finishes due to the infinite loop.
I learnt a bit of Python before iOS and with tkinter, your code would go into the mainloop. But I am not quite sure how to do the equivalent in Swift
Could someone please explain why I am having this problem and how to do this in Swift. Thanks.
var arrayimages: [UIImage] = [UIImage(named: "charizard")!,UIImage(named:"Flying_Iron_Man")!]
var x: Int = 0
var images: UIImage
let arraycount = arrayimages.count
repeat{
images = arrayimages[(x % arraycount)]
sleep(1)
slideshow.image = images
x++
} while true
NB: slideshow is an image view outlet.
You're looking for NSTimer
let timer = NSTimer.scheduledTimerWithTimeInterval(
1.0, target: self, selector: Selector("doYourTask"),
userInfo: nil, repeats: true)
The first argument is how frequently you want the timer to fire, the second is what object is going to have the selector that gets called, the third is the selector name, the fourth is any extra information you want to pass as a parameter on the timer object, and the fifth is whether this should repeat.
If you want to stop the code at any future point:
timer.invalidate()
Create a repeating NSTimer:
var timer = NSTimer.scheduledTimerWithTimeInterval(2.0,
target: self,
selector: "animateFunction:",
userInfo: nil,
repeats: true)
Then write a function animateFunction:
func animateFunction(timer: NSTimer)
{
//Display the next image in your array, or loop back to the beginning
}
Edit: Updated for modern Swift versions: (>= Swift 5)
This has changed a lot since I posted this answer. NSTimer is now called Timer in Swift, and the syntax of the scheduledTimer() method has changed. The method signature is now scheduledTimer(timeInterval:target:selector:userInfo:repeats:)
Also, the way you create a selector has changed
So the call would be
var timer = Timer.scheduledTimer(timeInterval: 2.0,
target: self,
selector: #selector(animateFunction(_:)),
userInfo: nil,
repeats: true)
And the animateFunction might look like this:
func animateFunction(timer: Timer)
{
//Display the next image in your array, or loop back to the beginning
}
I'm using the following code to open a URL with a UIButton in Swift
UIApplication.sharedApplication().openURL(url!)
This works very well on its own, but I'm looking for away to do this with an NSTimer with the goal being that the URL opens without any "buttons pressed" by the user.
Can anyone provide assistance?
Try like this in swift language
NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "timerFunctionRun", userInfo: nil, repeats: false)
and function Like ths
func timerFunctionRun () {
UIApplication.sharedApplication().openURL(url!)
}
its work fine ...
In Swift use:
dispatch_after(2.0, dispatch_get_main_queue(), {
// call your button action here
})
You don't really need a timer in your case unless you're repeating the opening of this URL.