addSubview from xib - iOS 8 vs iOS 9 - ios

Here is my viewController to add (View is in a .Xib file)
class EmptyFeedViewController: UIViewController {
#IBOutlet weak var view_center: UIView!
#IBOutlet weak var img_icon: UIImageView!
#IBOutlet weak var lbl_description: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.grayPale()
lbl_description.textColor = UIColor.grayMeduim()
lbl_description.text = "feed_empty".localizeFromFeedTable()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I add it like this from another viewController
let placeholderVC = EmptyFeedViewController()
addChildViewController(placeholderVC)
view_placeholder = placeholderVC.view
On iOS 9 it is working fine but on iOS 8 "lbl_description" is nil
How should I load my view for both OS ?

Since you are using Xibs, in order to get the IBOutlets populated, you should create a new instance of your view controller using the designated initializer - initWithNibName:bundle:
let placeholderVC = EmptyFeedViewController(nibName: "EmptyFeedViewController",
bundle: nil)

Related

How can I access data from a container view from the parent view controller in swift?

I have a view controller(SignUpController) and it has 1 image view at the top, 2 buttons at the bottom and 1 view as container view. The Container view(InfoRegisterController) contains scrollview with several text fields. Container view doesn’t contain any buttons. So, now i need to access text fields of Container view in the parent view controller (or can say as : I need to access all data from container view to parent view controller) so that I can register the user by clicking Register button at the bottom in SignUpController. I couldn’t solve it through delegates and NSUserDefaults too. So , Please help me to solve this in swift 4 ?
This is the parent view controller:
import UIKit
import Material
class SignUpController: UIViewController {
#IBOutlet weak var backgroundView: UIView!
#IBOutlet weak var register: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
backgroundView.layer.borderWidth = 1
backgroundView.layer.borderColor = UIColor.blue.cgColor
register.layer.cornerRadius = 5
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) // No need for semicolon
let tv: InfoRegisterController = self.childViewControllers[0] as!InfoRegisterController
print("Hello")
//tv.viewWillAppear(true)
}
All data must be accessed to this place so that I can post it to server.
#IBAction func Register(_ sender: Any) {
}
} // class end
Container View:
import UIKit
import Material
class InfoRegisterController: UIViewController, UITextFieldDelegate, UITableViewDelegate,UITableViewDataSource,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
#IBOutlet weak var fullName: TextField!
#IBOutlet weak var Email: ErrorTextField!
#IBOutlet weak var Password: TextField!
#IBOutlet weak var verifyPassword: TextField!
#IBOutlet weak var address: TextField!
#IBOutlet weak var permanentAddress: TextField!
#IBOutlet weak var currentAddress: TextField!
#IBOutlet weak var DOB: TextField!
#IBOutlet weak var occupation: TextField!
#IBOutlet weak var selectGender: TextField!
#IBOutlet weak var identificationType: TextField!
#IBOutlet weak var identificationID: TextField!
#IBOutlet weak var issuedDate: TextField!
#IBOutlet weak var issuedDistrict: TextField!
#IBOutlet weak var licenseNumber: TextField!
#IBOutlet weak var fathersName: TextField!
#IBOutlet weak var grandfathersName: TextField!
#IBOutlet weak var mobileNumber: TextField!
override func viewDidLoad() {
super.viewDidLoad()
self.fullName.delegate = self
self.Email.delegate = self
self.Password.delegate = self
self.verifyPassword.delegate = self
self.address.delegate = self
self.permanentAddress.delegate = self
self.currentAddress.delegate = self
self.DOB.delegate = self
self.occupation.delegate = self
self.identificationID.delegate = self
self.issuedDate.delegate = self
self.issuedDistrict.delegate = self
self.licenseNumber.delegate = self
self.fathersName.delegate = self
self.grandfathersName.delegate = self
self.mobileNumber.delegate = self
}
}
Here, I need to access all fields fullName,Email, Password,verifyPassword,address, permanentAddress,currentAddress, DOB,occupation and all others to SignUpController so that I can register new user.
To gain access to the container view from your parent, you will have to pass a reference from the container view to the parent and then use it in the parent view controller, there are many ways to do that and here is one of them.
In your viewDidAppear of InfoRegisterController which is the container view controller add the following code, this method will get a reference of InfoRegisterController into the parent to be used.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let signUpControllerParent = self.parent as! SignUpController
signUpControllerParent.saveContrainerViewRefference(vc: self)
}
Now in SignUpController add a local variable for the coming reference to be saved and used later to get the data from the textfields.
var infoRegisterRefferenceVC : InfoRegisterController?
Add this method also in your parent SignUpController
func saveContrainerViewRefference(vc:InfoRegisterController){
self.infoRegisterRefferenceVC = vc
}
Now you can have access to all the textfields and the methods in the container view from the parent for example:
var fullNameTextField = self.infoRegisterRefferenceVC.fullName.text
This should be it :)
There are several ways to accomplish this. You can use "Delegate" and "Protocol" or prepareForSegue method in parent view controller.
var somePropertyYouWantToAccess: NSString?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "yourChildViewSegueIdentifier" {
let childVc = segue.destinationViewController as ContainerViewController
self.somePropertyYouWantToAccess = childVc.firstName
}
}

iOS 8.4 - iboutlet not populating in programmatically created view controllers

When loading a UIViewController programmatically in iOS 8.4 I am consistently seeing the IBOutlets registering as nil. This is causing crashes on any iOS 8.4 device. The exact same code runs smoothly on iOS 9 and 9.0.1. For reference, this is a snippet of the view controller
class B8AVPermissionsViewController: B8BaseViewController {
#IBOutlet weak var closeButton: UIButton!
#IBOutlet weak var cameraButton: UIButton!
#IBOutlet weak var microphoneButton: UIButton!
var delegate: B8PermissionRequestingDelegate? = nil;
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated);
NSLog("cameraButton: \(cameraButton)")
}
That prints out cameraButton: nil
The code that creates this looks like:
self.permissionViewController = B8AVPermissionsViewController()
self.permissionViewController!.delegate = self
dispatch_async(dispatch_get_main_queue(), {
self.presentViewController(self.permissionViewController!, animated: true, completion: nil)
})
What am I doing wrong?
The problem is that there's bug in iOS 8. Saying B8AVPermissionsViewController() in iOS 8 does not automatically load the associated nib. You need to work around this; for example, you could call init(nibName:bundle:) explicitly and tell it where the nib is.
The bug is fixed in iOS 9, which is why you're not seeing the same problem there.

Resizing UITextView to fit content in Swift

This is my second view called detail view and I am bringing over text from the first view into the detail view. Some of the text is larger than others, so I am trying to make it to where my textview changes automatically to adapt to the amount of text needed. I am still new to Swift so any help is appreciated.
import UIKit
class DetailViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var symptomsTextView: UITextView!
#IBOutlet weak var stepsTextView: UITextView!
#IBOutlet weak var emergencyLabel: UILabel!
var medicalObject : MedicalInfo? = nil
var emergencyText = ""
var symptomsText = ""
var stepsText = ""
//Function to show text in labels and text views
override func viewWillAppear(animated: Bool) {
//Adding text to the labels and text views
emergencyLabel.text = emergencyText
symptomsTextView.text = symptomsText
stepsTextView.text = stepsText
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

How Do I Add UIViewController to UIScrollView in Swift

I want to have a UIScrollView of UIViewControllers. I tested the ScrollView and it works fine, except when I try to add the ViewControllers. The project builds fine, but I get a "fatal error: unexpectedly found nil while unwrapping an Optional value" error that points at the ViewController, particularly the line:
self.imageView.image = UIImage(named: self.image!)
However, when I inspect the object, I can see variables image and text have values in the ViewController. I'm using Xcode 6.3 Beta and building to iOS8.1 target.
Here's the code:
import UIKit
class ViewController: UIViewController {
//#IBOutlet weak var contentScrollView: UIScrollView!
#IBOutlet var contentScrollView: UIScrollView!
//test to make sure ScrollView functions
//let colors = [UIColor.redColor(),UIColor.blueColor(), UIColor.greenColor(), UIColor.whiteColor(), UIColor.blackColor(), UIColor.yellowColor()]
var frame = CGRectMake(0, 0, 0, 0)
var dataArray = [PostItem]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var da = PostItem(text: "test 1", pic: "beans.jpg")
self.dataArray.append(da!)
da = PostItem(text: "test 2", pic: "coffee.jpg")
self.dataArray.append(da!)
da = PostItem(text: "test 3", pic: "coffeeCup.jpg")
self.dataArray.append(da!)
for index in 0..<self.dataArray.count{
self.frame.origin.y = self.contentScrollView.frame.size.height * CGFloat(index)
self.frame.size = self.contentScrollView.frame.size
self.contentScrollView.pagingEnabled = false
let tempPost = self.dataArray[index]
var vc = PostViewController()
vc.text = tempPost.postText
vc.image = tempPost.postImage
self.contentScrollView.addSubview(vc.view)
}
self.contentScrollView.contentSize = CGSizeMake(self.view.frame.size.width, CGFloat(self.dataArray.count) * self.contentScrollView.frame.height)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}}
And here is the code for the ViewController I want to add:
import UIKit
class PostViewController: UIViewController {
//let postItem
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var postToFBButton: UIButton!
#IBOutlet weak var postToTwitterButton: UIButton!
#IBOutlet weak var postText: UILabel!
var image:String?
var text:String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.imageView.image = UIImage(named: self.image!)
self.postText.text = text!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}}
The fix is to create the PostViewController through instantiateViewControllerWithIdentifier from storyboard, this way, it will have an imageView loaded from storyboard when its view is added to the scrollview.

'IBOutlet' property has non-optional type 'UIButton'

Here's my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var button: 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.
}
}
It's a simple IBOutlet (straight from the Apple developer docs). It gives me the error "'IBOutlet' property has non-optional type 'UIButton'" and I have no idea how to fix it.
It should be like that (in Beta 3 or before):
#IBOutlet var button: UIButton?
IBOutlets must be optionals so place a ? behind the type.
It can also be-
#IBOutlet var button: UIButton!
or
#IBOutlet var weak button: UIButton! (in case you are not doing view unloading)
if you are using XCODE 6 Beta 4
class SecondViewController: UIViewController {
#IBOutlet weak var name: UILabel! = nil
override func viewDidLoad() {
super.viewDidLoad()
name.text="i m a label"
}
}
This code working fine
But when i replace #IBOutlet weak var name: UILabel? it is not working.

Resources