UIAlertController willDismiss alternative - iphone

I haven't done much iOS development in a while and while updating an old project I came across a question I couldn't find an answer for.
What is the replacement for
actionSheet:willDismissWithButtonIndex:
(emphasis on WILL)
I have some animation code that needs to execute at this point and currently I can only see how to execute my code after the sheet has been dismissed.
I'm sure the answer is right in front of my face, I just can't see it.

You can create a custom UIAlertController with a delgate and use that
import UIKit
#objc protocol CustomAlertControllerDelegate {
#objc optional func CustomAlertControllerWillDismiss(controller: CustomAlertController)
}
class CustomAlertController: UIAlertController {
weak var delegate:CustomAlertControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.delegate?.CustomAlertControllerWillDismiss!(controller: self)
}
}

Related

How to automatically play audio when entering a screen

I am learning Swift, and I am throwing myself in the deep end by building an app to force myself to learn the language. Something I want to implement is that when I transfer from screen 1 to screen 2, audio is played without needing to do anything. The audio is A-14a. The code below is set up so that when I click the Directions button, it plays the audio, but I don't know how to do it right away. Images are below to help show what I mean.
1st Screen 2nd Screen
The code I have is below:
import UIKit
import AVFoundation
class Intervention_Numerals1: UIViewController {
#IBOutlet weak var Directions: UIButton!
#IBOutlet weak var Done: UIButton!
var audioPlayer = AVAudioPlayer()
override func viewDidLoad() {
super.viewDidLoad()
setUpElements()
//Audio Test
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "A-N14a", ofType:"mp3")!))
audioPlayer.prepareToPlay()
} catch {
print(error)
}
}
func setUpElements() {
// Style the elements
Utilities.styleFilledButton(Directions)
Utilities.styleFilledButton(Done)
}
#IBAction func Play(_ sender: Any) {
audioPlayer.play()
}
}
Please let me know any advice on how to do this
Use this method
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
audioPlayer.play()
}
There are a couple of methods you can override to know the state of the view controller and add code to run when that state occurs.
As mentioned by Amila what you are looking for is probably viewDidAppear,
Another method that might also help you achieve this is viewWillAppear
I will provide the code of most of these methods and what they do below so you can try them all and experiment with them:
override func viewDidLoad() {
//This is what you already use every time, its called when the VC's view is loaded into memory
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//This happens when the view is *about* to appear, it happens before users see anything from the view, great for updating UI
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//This happens when the view actually appears on screen and when all the animations of loading the View Controller are over.
//not so good for updating UI since users will see a glimpse of previous view data.
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//This happens when the view is *about* to disappear, great example for this is when you begin swiping to go back in a navigation controller.
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
//This happens when view is no longer on screen for user to see, like when that swiping back animation in using navigation controller is *finished*
}
There are a few more of these such as viewWillLayoutSubviews and viewDidLayoutSubviews that occur when views inside your View Controller change.
Use all these to control when what happens, hope this helps :)

'NSInternalInconsistencyException', reason: 'Only run on the main thread!' swift 4

hey guys just wondering if you could help me debug this, this error comes up but only when i add a ui text view to a view controller here is everything i have for the view controller code as you can see i tried dispatchQueue but doesn't do anything.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
weak var textview: UITextView!
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Declare variable out side the viewDidLoad
import UIKit
class ViewController: UIViewController {
var textview: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
It looks like you're working with this controller from not-main thread. I think that you're trying to show the controller from some closure or async call. You have to ensure that your UI calls only from main thread.
Also you can debug it. Before you create/instantiate this controller set breakpoint and pay attention on debug navigator in XCode, you will be able to see where the program stopped, is this main thread or not.

Class has no initializers?

I have been working at this for about an hour now. I've looked at other questions n this sight with the exact same error and I tried there solutions. I am still getting the error though. Here is my code:
class Links: UIViewController {
let firstLinkButton: UIButton?
let secondLinkButton: UIButton?
#IBAction func firstLinkButton(sender: AnyObject) {
UIApplication.sharedApplication().openURL(NSURL(string: "http://www.google.com")!)
}
#IBAction func secondLinkButton(sender: AnyObject) {
UIApplication.sharedApplication().openURL(NSURL(string: "http://www.bing.com")!)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is probably the simplest question on this sight today but any input or suggestions are greatly appreciated. Thanks in advance.
P.S.: R.I.P. my reputation.
Make the buttons var
var firstLinkButton: UIButton?
var secondLinkButton: UIButton?
let constants must be initialized instantly.

PFTwitter Utils for Swift

racking my brain on this one but I am unable to get the PFTwitterUtils to work within swift.
I have imported all the relevant files from Parse (including PFTwitter Utils)
but it just won't recognise it for me to create an instance.
Does anyone know why this is happening? this is all I have so far
import UIKit
import Parse
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func loginWithTwitter(sender: AnyObject) {
PFTwitterUtils
}
}
Add import ParseTwitterUtils on the top of your ViewController

Linking View Controllers through button

I'm a beginner at all of this...Having said that I've come across a point in my app where I've stalled and don't know what to do or fix next. So any answers would be appreciated!
So in my Home View Controller, I have four buttons with four different categories.
Each of these categories has its own question list, but they have a common "General Question" list. The general question list has its own view controller.
When you click on any of the four buttons, it brings you to the General Question view. At the bottom of this view, I have a "Next" button.
Goal: Configure the Next button to continue to one of the category's question list based on what is initially pressed in the Home View Controller.
I've connected the buttons via outlet and action in the View Controller.
However, the Next button will not connect when I control + drag into the View Controller. I'm not sure where I need to put the code for this...
I was thinking that the code for the Next button might need to have some kind of conditional statement, but since it won't connect I can't even get that far.
Help!
(This is what I have) Sample Code:
import UIKit
import AddressBookUI
import AddressBook
import Foundation
import CoreData
import CoreGraphics
import EventKit
import EventKitUI
import CoreFoundation
class ViewController: UIViewController {
#IBOutlet var ColorButton: UIButton!
#IBOutlet var StyleButton: UIButton!
#IBOutlet var CutButton: UIButton!
#IBOutlet var MakeupButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var eventstore: EKEventStore!
var event: EKEvent!
weak var editViewDelegate: EKEventEditViewDelegate!
#IBAction func ColorButtonPressed(sender: UIButton) {
}
#IBAction func StyleButtonPressed(sender: UIButton) {
}
#IBAction func HaircutButtonPressed(sender: UIButton) {
}
#IBAction func MakeupButtonPressed(sender: UIButton) {
}
}
Here is a suggested approach as shown in the code below for 2 controllers (instead of 4) for brevity. Use appropriate named segues to each of the "next processing" controllers from the common processing controller and set up a chain. Here is a link to the project file: Project file
import UIKit
class ViewController: UIViewController {
var nextVcId = 0 // defines the button that is pressed
#IBAction func unwindFromOtherControllers(segue: UIStoryboardSegue) {
// In case you want to get back to the main VC
}
#IBAction func btn2Action(sender: UIButton) {
nextVcId = 0
self.performSegueWithIdentifier("commonSegue", sender: sender)
}
#IBAction func btn1Action(sender: UIButton) {
nextVcId = 1
self.performSegueWithIdentifier("commonSegue", sender: sender)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let vc = segue.destinationViewController as! CommonViewController
vc.nextControllerId = nextVcId
}
}
import UIKit
class CommonViewController: UIViewController {
var nextControllerId = 0
#IBOutlet weak var StatusLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.StatusLabel.text = "Common"
commonProcessing()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func commonProcessing() {
// do your common processing
if nextControllerId == 0 {
performSegueWithIdentifier("next1Segue", sender: self)
} else {
performSegueWithIdentifier("next2Segue", sender: self)
}
}
}
import UIKit
class Next1ViewController: UIViewController {
#IBOutlet weak var statusLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.statusLabel.text = "Next1"
next1Processing()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func next1Processing() {
println("Next 1 Processing")
}
}
import UIKit
class Next2ViewController: UIViewController {
#IBOutlet weak var statusLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
statusLabel.text = "Next 2"
next2Processing()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func next2Processing() {
println("Next 2 Processing")
}
}
processing