Skip to content

Instantly share code, notes, and snippets.

@jonfriskics
Created September 29, 2014 20:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonfriskics/3de4c85b70e71372bb10 to your computer and use it in GitHub Desktop.
Save jonfriskics/3de4c85b70e71372bb10 to your computer and use it in GitHub Desktop.
Is there something special that I have to do when unwrapping objects and getting access to the structs inside of them? This currently works with forced unwrapping, but not with optional binding/chaining. Check out lines 74 through 78 in ViewController.swift
//
// AppDelegate.swift
// Test
//
// Created by Jon Friskics on 9/29/14.
// Copyright (c) 2014 Code School. All rights reserved.
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
// MARK: ------ Property declarations
var window: UIWindow?
// MARK: ------ App delegate methods
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
let comicVC = ViewController()
let navController = UINavigationController(rootViewController: comicVC)
window?.rootViewController = navController
window?.makeKeyAndVisible()
return true
}
}
//
// ViewController.swift
// Test
//
// Created by Jon Friskics on 9/29/14.
// Copyright (c) 2014 Code School. All rights reserved.
//
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
lazy var scrollView:UIScrollView? = {
let sv = UIScrollView()
sv.delegate = self
sv.maximumZoomScale = 5.0
sv.backgroundColor = UIColor.lightGrayColor()
return sv
}()
lazy var imageView:UIImageView? = {
let iv = UIImageView()
iv.backgroundColor = UIColor.redColor()
iv.userInteractionEnabled = true
return iv
}()
func makeImage(color: UIColor) -> UIImage? {
let rect = CGRect(x: 0, y: 0, width: 250, height: 250)
UIGraphicsBeginImageContext(rect.size);
let context = UIGraphicsGetCurrentContext()
CGContextSetFillColorWithColor(context, UIColor.blueColor().CGColor)
CGContextFillRect(context, rect);
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return image;
}
override init() {
super.init(nibName: nil, bundle: nil)
self.automaticallyAdjustsScrollViewInsets = false
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.greenColor()
let image = makeImage(UIColor.blueColor())
imageView!.image = image
scrollView!.addSubview(imageView!)
if let sv = scrollView {
view.addSubview(sv)
}
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
imageView?.sizeToFit()
scrollView?.frame = CGRect(x: 0, y: topLayoutGuide.length, width: 200, height: 200)
println("\(imageView!.frame.size.width) \(imageView!.frame.size.height)")
// works
scrollView?.contentSize = CGSize(width: imageView!.frame.size.width, height: imageView!.frame.size.height)
// doesn't work
// scrollView?.contentSize = CGSize(width: imageView?.frame.size.width, height: imageView?.frame.size.height)
}
}
@jonfriskics
Copy link
Author

I guess it comes down to this - why is the frame CGRect an optional in addition to the UIImageView?

This code:

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()

        imageView?.sizeToFit()
        scrollView?.frame = CGRect(x: 0, y: topLayoutGuide.length, width: 200, height: 200)

        println("\(imageView!.frame.size.width) \(imageView!.frame.size.height)")

        let frame = imageView?.frame
        println("frame: \(frame)")
        let size = frame!.size
        println("size: \(size)")
        let width = size.width
        let height = size.height
        println("width: \(width), height: \(height)")

        scrollView?.contentSize = CGSize(width: imageView!.frame.size.width, height: imageView!.frame.size.height)
    }

Gives this output:

250.0 250.0
frame: Optional((0.0,0.0,250.0,250.0))
size: (250.0,250.0)
width: 250.0, height: 250.0

Which shows that the frame returned from the imageView optional is itself an optional, which just doesn't seem quite right. Especially since the UIView docs don't have frame:CGRect marked as an optional.

@jonfriskics
Copy link
Author

After researching a little bit more, it sounds like maybe the way to go is to declare the lazy objects as implicity unwrapped optionals, like this:

    lazy var imageView:UIImageView! = {
        let iv = UIImageView()
        iv.backgroundColor = UIColor.redColor()
        iv.userInteractionEnabled = true
        return iv
    }()

This makes some sense, because UIImageView() should never return nil. By declaring it as implicitly unwrapped after it has been created, the frame-setting is simplified to this:

        scrollView.contentSize = CGSize(width: imageView.frame.size.width, height: imageView.frame.size.height)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment