Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## Master

_No new commits since latest release yet_
* Add support for automatic cell registration by conforming to 'AutoRegistering' (table view / collection view).
[@apptekstudios](https://github.com/apptekstudios)
[#63](https://github.com/AliSoftware/Reusable/pull/63)

## 4.0.4

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Reusable
* This view is NOT loaded from a NIB (but defined entierly by code),
* that's why it's not annotated as `NibLoadable` but only `Reusable`
*/
final class MyColorSquareCell: UICollectionViewCell, Reusable {
final class MyColorSquareCell: UICollectionViewCell, Reusable, AutoRegistering {
private lazy var colorView: UIView = {
let colorView = UIView()
colorView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
Expand Down
6 changes: 5 additions & 1 deletion Example/ReusableDemo iOS/CollectionViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ final class CollectionViewController: UICollectionViewController {
guard let collectionView = self.collectionView else { return }

// Register cell classes
collectionView.register(cellType: MyColorSquareCell.self)
collectionView.register(cellType: MyXIBIndexSquaceCell.self)

/* Since MyColorSquareCell is marked as conforming to AutoRegistering,
there's no need to register this type ahead of time */
//collectionView.register(cellType: MyColorSquareCell.self)

// No need to register this one, the UIStoryboard already auto-register its cells
// self.collectionView.registerReusableCell(MyStoryBoardIndexPathCell)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Reusable
*
* That's why it's annotated with the `NibOwnerLoadable` protocol.
*/
final class MyHeaderTableView: UIView, NibOwnerLoadable {
final class MyTableViewHeader: UIView, NibOwnerLoadable {

@IBOutlet private weak var titleLabel: UILabel!
static let height: CGFloat = 55
Expand All @@ -30,6 +30,6 @@ final class MyHeaderTableView: UIView, NibOwnerLoadable {
}

func fillForSection(_ section: Int) {
self.titleLabel.text = "Header Section #\(section)"
self.titleLabel.text = "Header Section #\(section) (manual load)"
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14088"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MyHeaderTableView" customModule="ReusableDemo" customModuleProvider="target">
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MyTableViewHeader" customModule="ReusableDemo_iOS" customModuleProvider="target">
<connections>
<outlet property="titleLabel" destination="hYf-aH-s8i" id="WZ1-Km-cgw"/>
</connections>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// MyAutoRegisterHeaderTableView.swift
// ReusableDemo
//
// Created by TJB on 07/08/18.
// Copyright © 2018 ApptekStudios. All rights reserved.
//

import UIKit
import Reusable

/**
* This view is loaded from a NIB, and is the XIB file's
* root view (and not the File's Owner). => it is `NibLoadable`
*
* It is also reusable and has a `reuseIdentifier` (as it's a TableViewHeaderFooterView
* and it uses the TableView recycling mechanism) => it is `Reusable`
*
* That's why it's annotated with the `NibReusable` typealias,
* Which in fact is just a convenience typealias that combines
* `NibLoadable` & `Reusable` protocols.
*/
final class MyTableViewHeaderAutoRegistering: UITableViewHeaderFooterView, NibReusable, AutoRegistering {

@IBOutlet private weak var titleLabel: UILabel!

static let height: CGFloat = 55

func fillForSection(_ section: Int) {
self.titleLabel.text = "Header Section #\(section)"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14283.14"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="okZ-6Z-SVm" customClass="MyTableViewHeaderAutoRegistering" customModule="ReusableDemo_iOS" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="298.5" height="55"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5FU-EW-ITI">
<rect key="frame" x="0.0" y="0.0" width="298.5" height="55"/>
<color key="backgroundColor" red="0.20392156862745098" green="0.45098039215686275" blue="0.72941176470588232" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="My HeaderView" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hYf-aH-s8i">
<rect key="frame" x="8" y="13" width="121" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zZ4-Xm-Xca" userLabel="Blue Bar">
<rect key="frame" x="8" y="42" width="239" height="5"/>
<color key="backgroundColor" red="0.80177218539999995" green="0.88913449410000001" blue="0.95461380880000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="5" id="k9e-UV-gvq"/>
</constraints>
</view>
</subviews>
<constraints>
<constraint firstItem="hYf-aH-s8i" firstAttribute="leading" secondItem="zZ4-Xm-Xca" secondAttribute="leading" id="Q4E-ve-ADj"/>
<constraint firstAttribute="trailing" secondItem="5FU-EW-ITI" secondAttribute="trailing" id="cAb-OQ-i7v"/>
<constraint firstAttribute="bottom" secondItem="zZ4-Xm-Xca" secondAttribute="bottom" constant="8" id="g2M-WH-Mhw"/>
<constraint firstItem="5FU-EW-ITI" firstAttribute="leading" secondItem="okZ-6Z-SVm" secondAttribute="leading" id="hue-vz-jI7"/>
<constraint firstItem="zZ4-Xm-Xca" firstAttribute="top" secondItem="hYf-aH-s8i" secondAttribute="bottom" constant="8" symbolic="YES" id="kvp-aL-8Hr"/>
<constraint firstItem="zZ4-Xm-Xca" firstAttribute="leading" secondItem="okZ-6Z-SVm" secondAttribute="leading" constant="8" id="orC-Gd-rNO"/>
<constraint firstItem="zZ4-Xm-Xca" firstAttribute="width" secondItem="okZ-6Z-SVm" secondAttribute="width" multiplier="8/10" id="owR-gy-XJA"/>
<constraint firstAttribute="bottom" secondItem="5FU-EW-ITI" secondAttribute="bottom" id="tc9-uM-9sG"/>
<constraint firstItem="5FU-EW-ITI" firstAttribute="top" secondItem="okZ-6Z-SVm" secondAttribute="top" id="wsU-Ky-EUd"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="titleLabel" destination="hYf-aH-s8i" id="TCO-Yc-dDI"/>
</connections>
<point key="canvasLocation" x="356.25" y="211.5"/>
</view>
</objects>
</document>
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import Reusable
* Which in fact is just a convenience typealias that combines
* `NibLoadable` & `Reusable` protocols.
*/
final class MyXIBInfoCell: UITableViewCell, NibReusable {
final class MyXIBInfoCell: UITableViewCell, NibReusable, AutoRegistering {

@IBOutlet private weak var titleLabel: UILabel!
private var info: String = "<Info?>"
Expand Down
46 changes: 31 additions & 15 deletions Example/ReusableDemo iOS/TableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,44 @@ final class TableViewController: UITableViewController {

tableView.register(cellType: MySimpleColorCell.self)
tableView.register(cellType: MyXIBTextCell.self)
tableView.register(cellType: MyXIBInfoCell.self)

/* Since MyXIBInfoCell is marked as conforming to AutoRegistering,
there's no need to register this type ahead of time */
// tableView.register(cellType: MyXIBInfoCell.self)

/* No need to register this one, the UIStoryboard already auto-register its cells */
// tableView.registerReusableCell(MyStoryBoardIndexPathCell)
// tableView.registerReusableCell(MyStoryBoardIndexPathCell)
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return MyHeaderTableView.height
switch section {
case 0:
return MyTableViewHeader.height
default:
return MyTableViewHeaderAutoRegistering.height
}
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let frame = CGRect(
x: 0,
y: 0,
width: tableView.bounds.size.width,
height: self.tableView(tableView, heightForHeaderInSection: section)
)
// See the overridden `MyHeaderTableView.init(frame:)` initializer, which
// automatically loads the view content from its nib using loadNibContent()
let view = MyHeaderTableView(frame: frame)

view.fillForSection(section)
return view
switch section {
case 0:
let frame = CGRect(
x: 0,
y: 0,
width: tableView.bounds.size.width,
height: self.tableView(tableView, heightForHeaderInSection: section)
)
// See the overridden `MyHeaderTableView.init(frame:)` initializer, which
// automatically loads the view content from its nib using loadNibContent()
let view = MyTableViewHeader(frame: frame)
view.fillForSection(section)
return view
default:
// This header class is set to auto-register itself
let view: MyTableViewHeaderAutoRegistering = tableView.dequeueReusableHeaderFooterView()
view.fillForSection(section)
return view
}
}

override func numberOfSections(in tableView: UITableView) -> Int {
Expand All @@ -61,6 +76,7 @@ final class TableViewController: UITableViewController {
textCell.fill("{section \(indexPath.section), row \(indexPath.row)}")
return textCell
case 2:
// Note that auto-register is enabled here
let infoCell = tableView.dequeueReusableCell(for: indexPath) as MyXIBInfoCell
infoCell.fill("InfoCell #\(indexPath.row)", info: "Info #\(indexPath.row)", details: "Details #\(indexPath.row)")
return infoCell
Expand Down
Loading