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.
Related
I'm trying to set an image as the title of a navigation bar in swift using the code below. The code builds successfully, but the image does not display. Any advice would be appreciated.
import UIKit
class FirstViewController: UIViewController {
#IBOutlet weak var navigationBar: UINavigationItem!
var convoImage: UIImage!
var convoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.convoImage = UIImage(contentsOfFile: "conversation.png")
self.convoImageView = UIImageView(image: self.convoImage)
self.navigationBar.titleView = self.convoImageView
}
}
Set the navigationItem's titleView.
let image = UIImage(named: "image_name.png")
self.navigationItem.titleView = UIImageView(image: image)
In your code replace below line:
self.convoImage = UIImage(contentsOfFile: "conversation.png")
with
self.convoImage = UIImage(named: "conversation.png")
You should set convoImageView frame .
import UIKit
class FirstViewController: UIViewController {
#IBOutlet weak var navigationBar: UINavigationItem!
var convoImage: UIImage!
var convoImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.convoImage = UIImage(named: "conversation.png")
self.convoImageView = UIImageView(image: self.convoImage)
self.convoImageView.frame = CGRectMake(0,0,720,100)
self.navigationBar.titleView = self.convoImageView
}
}
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.
}
}
Is it possible to make an array of UIButtons?
let buttonArray: [UIButton] = [UIButton(Button1)!, UIButton(Button2)!, UIButton(Button3)!]
To reference later as
buttonArray[0].setImage(UIImage, forState: UIControlState.Normal)
Or somehow set a
var button = UIButton.whoseName = "Specific String"
button.setImage(UIImage, forState: UIControlState.Normal)
VC1:
import UIKit
class VC1: UIViewController {
#IBOutlet weak var Card1: UIButton!
#IBOutlet weak var Card2: UIButton!
#IBOutlet weak var Card3: UIButton!
let Cards: [UIImage] = [UIImage(named: "Default")!, UIImage(named: "2s")!,UIImage(named: "2h")!,UIImage(named: "2c")!,UIImage(named: "2d")!,]
// var CardCaller: Array<UIButton> = [Card1, Card2, Card3]
let CardCallers: [UIButton] = [Card1, Card2, Card3] //ERROR: 'VC1.Type' does not have a member named 'Card1'
var caller = ""
var Index2 = Int()
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 KVC = segue.destinationViewController as VC2
KVC.source = segue.identifier!
}
#IBAction func unwind(unwindSegue: UIStoryboardSegue){
//Card1.setImage(Cards[Index2], forState: UIControlState.Normal)
//let button = UIButton(named: "Card1")!
if caller == "Card1" {Card1.setImage(Cards[Index2], forState: UIControlState.Normal)} else if caller == "Card2" {Card2.setImage(Cards[Index2], forState: UIControlState.Normal)} else if caller == "Card3" {Card3.setImage(Cards[Index2], forState: UIControlState.Normal)}
}
#IBAction func text(sender: AnyObject) {
println(caller)
println(Index2)
}
}
The IBOutlets are wired properly to Storyboard buttons; I created them with control/drag to the view controller.
This shouldn't be a problem, but it may have something to do with when you're accessing the buttons. Try creating the array globally and adding the buttons to it once they've loaded:
class VC1: UIViewController {
#IBOutlet weak var Card1: UIButton!
#IBOutlet weak var Card2: UIButton!
#IBOutlet weak var Card3: UIButton!
var CardCallers: [UIButton] = [UIButton]() // Empty UIButton array
override func viewDidLoad() {
self.CardCallers = [self.Card1, self.Card2, self.Card3] // Buttons have now loaded in the view
}
}
You can.
Two ways to do it:
var buttonsArray: Array<UIButton> = [button1, button2]
Or
#IBOutlet var buttonsArray: Array<UIButton> = []
For the later one, it can be filled from the storyboard as an IBOutletCollection
Please note that views can be assigned to an IBOutlet and an IBOutletCollection at the same time.
Absolute Swift beginner here.
I have been trying to get a simple set of png's to animate.
Here is what I have:
Any help would be much appreciated.
Thanks
#import <UIKit/UIKit.h>
class ViewController: UIViewController {
#IBOutlet var myImageView : UIImageView
#IBOutlet var animationBtn : UIButton
var imageList = UIImage[]()
#IBAction func animationBtnClicked(sender : AnyObject) {
startAnimation()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for i in 1...13
{
let imageName = "\(i)"
imageList += UIImage(named: imageName)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startAnimation() -> Void
{
if !myImageView.isAnimating()
{
myImageView.animationImages = imageList
myImageView.startAnimating()
animationBtn.setTitle("Stop Animation", forState: UIControlState.Normal)
} else
{
myImageView.stopAnimating()
myImageView.image = UIImage(named:"bomb.jpg")
animationBtn.setTitle("Start Animation", forState: UIControlState.Normal)
}
}
}
Here is the adjusted code if it helps anyone.
Cheers
import UIKit
class ViewController: UIViewController {
#IBOutlet var myImageView: UIImageView!
#IBOutlet var animationBtn: UIButton!
var imageList = [UIImage]()
#IBAction func animationBtnClicked(sender: AnyObject) {
startAnimation()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
for i in 1...99
{
let imageName = "\(i)"
imageList.append(UIImage(named: imageName)!)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func startAnimation() -> Void
{
myImageView.animationImages = imageList
myImageView.startAnimating()
}
}
Those errors messages shows the exact issue.
Issue 1
For fixing has no initializers, you need implement at-least one init function in your class.
Issue 2
For fixing IBOutlet has non-optional, you need to change your IBOutlet variables to optionals.
#IBOutlet var myImageView : UIImageView!
#IBOutlet var animationBtn : UIButton!
Issue 3
For fixing that [UIImage] is not identical to UInt8. The += can't be used to append a single UIImage to [UIImage]
You need to change:
imageList += UIImage(named: imageName)
to
imageList.append(UIImage(named: imageName))
How do I make an array of UILabel in Swift. When I try to, I get an error like ViewController.Type'dose not have a member named 'Lable00'
my code:
import UIKit
class ViewController: UIViewController {
let individualScores = [75, 43, 103, 87, 12]
#IBOutlet var Lable00: UILabel?
#IBOutlet var Lable01: UILabel?
#IBOutlet var Lable02: UILabel?
#IBOutlet var Lable03: UILabel?
#IBOutlet var Lable04: UILabel?
var Lable_Arr = [Lable00, Lable01, Lable02, Lable03, Lable04]
override func viewDidLoad() {
super.viewDidLoad()
for score in individualScores {
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
private var labels:[UILabel]()
override func viewDidLoad()
{
super.viewDidLoad()
labels.append(Lable00)
labels.append(Lable01)
labels.append(Lable02)
labels.append(Lable03)
labels.append(Lable04)
// do stuff with the labels view
}
for Swift 2 :
var labels:[UILabel]=[]
In ViewDid load you don't have to append, you can just assign a new array to labels like so:
var labels:[UILabel]()
override func viewDidLoad() {
super.viewDidLoad()
labels = [label01, label02, label03, label04]
// do stuff with the labels view
}