11
votes

I have a custom UIView subclass with three subviews added to it via Nib file (a UIImageView, a UIView and a UITextField) and IBOutlets set. But when the awakeFromNib or initWithCoder get called in the subclass then all IBOutlets are nil and even the subviews array is empty.

I'm using Swift and XCode 6 beta 5 where this UIView subclass is in a framework and I added the UIView subclass to a Storyboard within my project so I can use the new Live View technology. But I can't see the added subviews in the Live View either which is very sad.

I couldn't find any way to fix this, here's the code from my UIView subclass:

import UIKit

@IBDesignable public class BlurredSheetEntryView: UIView {

    @IBOutlet var iconImageView: UIImageView?
    @IBOutlet var separatorView: UIView?
    @IBOutlet public var textField: UITextField?

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required public init(coder aDecoder: NSCoder!) {
        super.init(coder: aDecoder)

        for subView in self.subviews {
            println("subView: \(subView)")
        }

        println("self.textField: \(self.textField)")
        println("self.iconImageView: \(self.iconImageView)")
        println("self.separatorView: \(self.separatorView)")
    }

    override public func awakeFromNib() {

        for subView in self.subviews {
            println("subView: \(subView)")
        }

        println("self.textField: \(self.textField)")
        println("self.iconImageView: \(self.iconImageView)")
        println("self.separatorView: \(self.separatorView)")

    }
}

And my Nib file looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6205" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6198"/>
        <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="BlurredSheetEntryView" customModule="BlurredSheetEntry" customModuleProvider="target">
            <rect key="frame" x="0.0" y="0.0" width="300" height="50"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZnN-gy-Mc6">
                    <rect key="frame" x="8" y="5" width="40" height="40"/>
                    <constraints>
                        <constraint firstAttribute="width" secondItem="ZnN-gy-Mc6" secondAttribute="height" multiplier="1:1" id="C4N-zC-woh"/>
                    </constraints>
                </imageView>
                <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Placeholder" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="npg-xI-NSo">
                    <rect key="frame" x="66" y="8" width="226" height="34"/>
                    <fontDescription key="fontDescription" type="system" pointSize="15"/>
                    <textInputTraits key="textInputTraits"/>
                </textField>
                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8lA-9y-yoA">
                    <rect key="frame" x="56" y="5" width="2" height="40"/>
                    <color key="backgroundColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
                    <constraints>
                        <constraint firstAttribute="width" constant="2" id="QgG-pW-8q0"/>
                    </constraints>
                </view>
            </subviews>
            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
            <constraints>
                <constraint firstAttribute="bottom" secondItem="8lA-9y-yoA" secondAttribute="bottom" constant="5" id="51o-Il-vGA"/>
                <constraint firstItem="8lA-9y-yoA" firstAttribute="leading" secondItem="ZnN-gy-Mc6" secondAttribute="trailing" constant="8" id="AEG-I2-vsT"/>
                <constraint firstAttribute="bottom" secondItem="npg-xI-NSo" secondAttribute="bottom" constant="8" id="E0H-fN-lg4"/>
                <constraint firstItem="8lA-9y-yoA" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="5" id="EYR-L8-96J"/>
                <constraint firstAttribute="bottom" secondItem="ZnN-gy-Mc6" secondAttribute="bottom" constant="5" id="GFW-R2-jGI"/>
                <constraint firstAttribute="trailing" secondItem="npg-xI-NSo" secondAttribute="trailing" constant="8" id="Lws-lv-n37"/>
                <constraint firstItem="ZnN-gy-Mc6" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="5" id="Pv0-ZV-aT4"/>
                <constraint firstItem="ZnN-gy-Mc6" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="8" id="XOI-jO-Sv7"/>
                <constraint firstItem="npg-xI-NSo" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="8" id="dA3-Wg-XfN"/>
                <constraint firstItem="npg-xI-NSo" firstAttribute="leading" secondItem="8lA-9y-yoA" secondAttribute="trailing" constant="8" id="mq6-6r-Z2b"/>
            </constraints>
            <nil key="simulatedStatusBarMetrics"/>
            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
            <connections>
                <outlet property="iconImageView" destination="ZnN-gy-Mc6" id="0Hp-sr-mqx"/>
                <outlet property="separatorView" destination="8lA-9y-yoA" id="VFx-En-K3c"/>
                <outlet property="textField" destination="npg-xI-NSo" id="tIy-N2-g2j"/>
            </connections>
            <point key="canvasLocation" x="371" y="327"/>
        </view>
    </objects>
</document>

UPDATE: I've created an absolutely simple example project where I only did the following:

  • choose Master-View template for iOS
  • add new Framework called "MyCustomTableViewCell" with Xib file
  • add a UIView with blue background color as a subview in Xib file
  • add @IBOutlet and connection in the Swift file
  • add a println() statement within awakeFromNib() in Swift file
  • set the class of Cells in the Master tableView to the subclass from the framework

When I build & run and click the "+"-Sign on the top right corner, I get "nil" printed out on the console as a result for the @IBOutlet. This is my issue and what annoys me. But maybe I'm doing something wrong here ...

I've uploaded the example project, here's the download url: https://www.dropbox.com/s/vcb0sa98tw6i1iv/NilObjectsFromXib.zip?dl=0

I'm using a framework because I have to as I want to see my subclass as a Live View in my Main storyboard.

Thanks for any help in advance! :)

1
How are you creating the instance of BlurredSheetEntryView?Snowman
I'm creating it by adding it as a subview to a Storyboard.Jeehut
Btw: This still happens with XCode 6 Beta 6 and I filed a bug with Apple right after this post here. (17957402) Hope they will fix it soon. Does anyone know a workaround?Jeehut
I've updated my question with an example project, where you can see the issue when you click on the "+" on the top right corner and have a look at the console.Jeehut
@Dschee could you attach a link to this open radar issue? I can not find it so maybe it was removed or something.Julian

1 Answers

-1
votes

I reviewed your project and: You need to add your XIB file to Copy bundle resourses in project settings

You need to register custom cell XIB for using in your table view via:

 override func viewDidLoad() {
        super.viewDidLoad()
        self.tableView.registerNib(UINib(nibName:"MyCustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CustomCell")
    }

Then you can use your custom cell in your table:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("CustomCell", forIndexPath: indexPath) as MyCustomTableViewCell

    // Do something with your cell

    return cell
}