Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RefreshControlDesignable example #429

Merged
merged 9 commits into from Apr 4, 2017
Merged
4 changes: 2 additions & 2 deletions CHANGELOG.md
Expand Up @@ -16,8 +16,8 @@ All notable changes to this project will be documented in this file.
[#403](https://github.com/IBAnimatable/IBAnimatable/pull/403) by [@tbaranes](https://github.com/tbaranes)
- Make images of `AnimatableSlider` designable.
[#417](https://github.com/IBAnimatable/IBAnimatable/pull/417) by [@phimage](https://github.com/phimage)
- Add `AnimatableTableViewController` to support `UIRefreshControl` customization.
[#418](https://github.com/IBAnimatable/IBAnimatable/pull/418) by [@phimage](https://github.com/phimage)
- Add `RefreshControlDesignable` to make `UIRefreshControl` customization available in Interface Builder. Currently supported by `UITableViewController` and `UITableView`
[#418](https://github.com/IBAnimatable/IBAnimatable/pull/418) by [@phimage](https://github.com/phimage) and [#429](https://github.com/IBAnimatable/IBAnimatable/pull/429) by [@tbaranes](https://github.com/tbaranes)

#### Bugfixes
- Make corner sides case insensitive.
Expand Down
17 changes: 17 additions & 0 deletions Documentation/APIs.md
Expand Up @@ -167,17 +167,34 @@ Easily add color layer on top of the UI element especially `AnimatableImageView`
| toneOpacity | CGFloat | opacity of tone color. The default value is `CGFloat.NaN`. |

#### `ViewControllerDesignable`

| Property name | Data type | Description |
| ------------- |:-------------:| ----- |
| hideNavigationBar | Bool | whether to hide navigation bar. The default value is `false`. |

#### `RefreshControlDesignable`


| Property name | Data type | Description |
| ------------- |:-------------:| ----- |
| hasRefreshControl | Bool | whether to add a `UIRefreshControl`. The default value is `false`. |
| refreshControlTintColor | Optional<UIColor> | tint color of the `UIRefreshControl` |
| refreshControlBackgroundColor | Optional<UIColor> | background color of the `UIRefreshControl` |

**Note:** `AnimatableTableView` conforms to that protocol, **but** if your deployment target is less than 10, you will have to add your `UIRefreshControl` yourself:

```
let refreshControl: UIRefreshControl?
if #available(iOS 10.0, *) {
refreshControl = tableView.refreshControl
} else {
refreshControl = UIRefreshControl()
tableView.addSubview(refreshControl!)
tableView.configureRefreshController()
}
refreshControl?.addTarget(self, action: #selector(refresh(_:)), for: .valueChanged)
```

#### `SliderImagesDesignable`

| Property name | Data type | Description |
Expand Down
20 changes: 14 additions & 6 deletions IBAnimatable.xcodeproj/project.pbxproj
Expand Up @@ -8,7 +8,7 @@

/* Begin PBXBuildFile section */
33A8B9ED1C7E790800082529 /* SystemCubeAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33A8B9EB1C7E790800082529 /* SystemCubeAnimator.swift */; };
48D436311E8E221500538E7D /* RefreshTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D436301E8E221500538E7D /* RefreshTableViewController.swift */; };
48D436311E8E221500538E7D /* RefreshControlTableViewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48D436301E8E221500538E7D /* RefreshControlTableViewViewController.swift */; };
7305EC0E1E1996E000BF4C9A /* AnimationChainable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7305EC0D1E1996E000BF4C9A /* AnimationChainable.swift */; };
731205811D28A3830009BCAC /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 731205801D28A3830009BCAC /* Utils.swift */; };
732485D71D4902510068FD93 /* ParamType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 732485D61D4902510068FD93 /* ParamType.swift */; };
Expand Down Expand Up @@ -105,8 +105,8 @@
AEE552AE1C82D1E1009CF623 /* PresentFadeSegue.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE552AC1C82D1E1009CF623 /* PresentFadeSegue.swift */; };
AEE552B11C839EB7009CF623 /* TransitionPresenterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE552AF1C839EB7009CF623 /* TransitionPresenterManager.swift */; };
AEF4938D1CE0161C00B76FD6 /* Playground.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AEF4938C1CE0161C00B76FD6 /* Playground.storyboard */; };
C4B4AD551E8645FD007A79A4 /* BackgroundImageDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B4AD541E8645FD007A79A4 /* BackgroundImageDesignable.swift */; };
C47A737C1E86A9BD0044EFF8 /* SliderImagesDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47A737B1E86A9BD0044EFF8 /* SliderImagesDesignable.swift */; };
C4B4AD551E8645FD007A79A4 /* BackgroundImageDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B4AD541E8645FD007A79A4 /* BackgroundImageDesignable.swift */; };
C4B504E01E8832E7001E096A /* RefreshControlerDesignable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B504DF1E8832E7001E096A /* RefreshControlerDesignable.swift */; };
C4B504E51E8833C4001E096A /* AnimatableTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4B504E41E8833C4001E096A /* AnimatableTableViewController.swift */; };
CAB5610BC7B5D20C927AAB87 /* Navigator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAB5692C91C9ECC8018DE83E /* Navigator.swift */; };
Expand Down Expand Up @@ -142,6 +142,8 @@
E27691EB1CAFC91A004A725C /* SystemPushAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27691EA1CAFC91A004A725C /* SystemPushAnimator.swift */; };
E27691EF1CAFCA29004A725C /* SystemRevealAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27691EE1CAFCA29004A725C /* SystemRevealAnimator.swift */; };
E27691F31CAFCD67004A725C /* SystemRotateAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27691F21CAFCD67004A725C /* SystemRotateAnimator.swift */; };
E27F1D5C1E90EAC900BAB013 /* RefreshControl.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E27F1D5B1E90EAC900BAB013 /* RefreshControl.storyboard */; };
E27F1D601E90F16200BAB013 /* RefreshControlTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27F1D5F1E90F16200BAB013 /* RefreshControlTableViewController.swift */; };
E28E28211D6CCA5C0043D56E /* ActivityIndicatorAnimationAudioEqualizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28E28051D6CCA5C0043D56E /* ActivityIndicatorAnimationAudioEqualizer.swift */; };
E28E28221D6CCA5C0043D56E /* ActivityIndicatorAnimationBallClipRotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28E28061D6CCA5C0043D56E /* ActivityIndicatorAnimationBallClipRotate.swift */; };
E28E28231D6CCA5C0043D56E /* ActivityIndicatorAnimationBallClipRotateMultiple.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28E28071D6CCA5C0043D56E /* ActivityIndicatorAnimationBallClipRotateMultiple.swift */; };
Expand Down Expand Up @@ -221,7 +223,7 @@

/* Begin PBXFileReference section */
33A8B9EB1C7E790800082529 /* SystemCubeAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemCubeAnimator.swift; sourceTree = "<group>"; };
48D436301E8E221500538E7D /* RefreshTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshTableViewController.swift; sourceTree = "<group>"; };
48D436301E8E221500538E7D /* RefreshControlTableViewViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlTableViewViewController.swift; sourceTree = "<group>"; };
7305EC0D1E1996E000BF4C9A /* AnimationChainable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationChainable.swift; sourceTree = "<group>"; };
731205801D28A3830009BCAC /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
732485D61D4902510068FD93 /* ParamType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParamType.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -316,8 +318,8 @@
AEEE200C1C18D10C00AD033B /* DesignableNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DesignableNavigationBar.swift; sourceTree = "<group>"; };
AEEF86BD1CA8E9E200899AAB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AEF4938C1CE0161C00B76FD6 /* Playground.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Playground.storyboard; sourceTree = "<group>"; };
C4B4AD541E8645FD007A79A4 /* BackgroundImageDesignable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundImageDesignable.swift; sourceTree = "<group>"; };
C47A737B1E86A9BD0044EFF8 /* SliderImagesDesignable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SliderImagesDesignable.swift; sourceTree = "<group>"; };
C4B4AD541E8645FD007A79A4 /* BackgroundImageDesignable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundImageDesignable.swift; sourceTree = "<group>"; };
C4B504DF1E8832E7001E096A /* RefreshControlerDesignable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlerDesignable.swift; sourceTree = "<group>"; };
C4B504E41E8833C4001E096A /* AnimatableTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimatableTableViewController.swift; sourceTree = "<group>"; };
CAB562E75DABEED7FCE0F309 /* FillDesignable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FillDesignable.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -360,6 +362,8 @@
E27691EA1CAFC91A004A725C /* SystemPushAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemPushAnimator.swift; sourceTree = "<group>"; };
E27691EE1CAFCA29004A725C /* SystemRevealAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemRevealAnimator.swift; sourceTree = "<group>"; };
E27691F21CAFCD67004A725C /* SystemRotateAnimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemRotateAnimator.swift; sourceTree = "<group>"; };
E27F1D5B1E90EAC900BAB013 /* RefreshControl.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = RefreshControl.storyboard; sourceTree = "<group>"; };
E27F1D5F1E90F16200BAB013 /* RefreshControlTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlTableViewController.swift; sourceTree = "<group>"; };
E28E28051D6CCA5C0043D56E /* ActivityIndicatorAnimationAudioEqualizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationAudioEqualizer.swift; sourceTree = "<group>"; };
E28E28061D6CCA5C0043D56E /* ActivityIndicatorAnimationBallClipRotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationBallClipRotate.swift; sourceTree = "<group>"; };
E28E28071D6CCA5C0043D56E /* ActivityIndicatorAnimationBallClipRotateMultiple.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorAnimationBallClipRotateMultiple.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -614,8 +618,9 @@
733323021D56BCF200B88F6E /* UserInterfaceTableViewController.swift */,
73A99B661D5FC8650079C7EC /* BorderViewController.swift */,
E2E62B8A1D69BE3800294A73 /* UserInterfaceActivityIndicatorViewController.swift */,
48D436301E8E221500538E7D /* RefreshTableViewController.swift */,
90F04E681DDDC650007614CB /* CornerViewController.swift */,
E27F1D5F1E90F16200BAB013 /* RefreshControlTableViewController.swift */,
48D436301E8E221500538E7D /* RefreshControlTableViewViewController.swift */,
);
name = code;
sourceTree = "<group>";
Expand Down Expand Up @@ -826,6 +831,7 @@
AE0D30991CE149150093B578 /* UserInterface.storyboard */,
AE87646B1D232F1D0044E0AB /* UserInterfaceMask.storyboard */,
E2E62B881D69BDEF00294A73 /* UserInterfaceActivityIndicator.storyboard */,
E27F1D5B1E90EAC900BAB013 /* RefreshControl.storyboard */,
);
name = UserInterface;
sourceTree = "<group>";
Expand Down Expand Up @@ -989,6 +995,7 @@
AE0D309C1CE14A170093B578 /* Animations.storyboard in Resources */,
AE154B101C788A560093C05B /* Transitions.storyboard in Resources */,
AEF4938D1CE0161C00B76FD6 /* Playground.storyboard in Resources */,
E27F1D5C1E90EAC900BAB013 /* RefreshControl.storyboard in Resources */,
E2E62B891D69BDEF00294A73 /* UserInterfaceActivityIndicator.storyboard in Resources */,
AE0D309A1CE149150093B578 /* UserInterface.storyboard in Resources */,
AE87646C1D232F1D0044E0AB /* UserInterfaceMask.storyboard in Resources */,
Expand Down Expand Up @@ -1198,7 +1205,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
48D436311E8E221500538E7D /* RefreshTableViewController.swift in Sources */,
48D436311E8E221500538E7D /* RefreshControlTableViewViewController.swift in Sources */,
733323031D56BCF200B88F6E /* UserInterfaceTableViewController.swift in Sources */,
AE1B9A661CE3EB100098D962 /* InteractionTableViewController.swift in Sources */,
73A99B671D5FC8650079C7EC /* BorderViewController.swift in Sources */,
Expand All @@ -1220,6 +1227,7 @@
90F04E691DDDC650007614CB /* CornerViewController.swift in Sources */,
AED1A1031BFE9820001346FA /* AppDelegate.swift in Sources */,
732485D71D4902510068FD93 /* ParamType.swift in Sources */,
E27F1D601E90F16200BAB013 /* RefreshControlTableViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
20 changes: 19 additions & 1 deletion IBAnimatable/AnimatableTableView.swift
Expand Up @@ -7,7 +7,8 @@ import UIKit

@IBDesignable
open class AnimatableTableView: UITableView, FillDesignable, BorderDesignable, GradientDesignable,
BackgroundImageDesignable, BlurDesignable, Animatable {
BackgroundImageDesignable, BlurDesignable, RefreshControlDesignable,
Animatable {

// MARK: - FillDesignable
@IBInspectable open var fillColor: UIColor? {
Expand Down Expand Up @@ -121,6 +122,23 @@ open var startPoint: GradientStartPoint = .top
}
}

// MARK: - RefreshControlDesignable
@IBInspectable open var hasRefreshControl: Bool = false {
didSet {
configureRefreshController()
}
}
@IBInspectable open var refreshControlTintColor: UIColor? {
didSet {
configureRefreshController()
}
}
@IBInspectable open var refreshControlBackgroundColor: UIColor? {
didSet {
configureRefreshController()
}
}

// MARK: - Animatable
open var animationType: AnimationType = .none
@IBInspectable var _animationType: String? {
Expand Down
1 change: 0 additions & 1 deletion IBAnimatable/AnimatableTableViewController.swift
Expand Up @@ -40,7 +40,6 @@ open class AnimatableTableViewController: UITableViewController, ViewControllerD
}

// MARK: - RefreshControlDesignable

@IBInspectable open var hasRefreshControl: Bool = false {
didSet {
configureRefreshController()
Expand Down
38 changes: 30 additions & 8 deletions IBAnimatable/RefreshControlerDesignable.swift
Expand Up @@ -25,18 +25,40 @@ public protocol RefreshControlDesignable {
public extension RefreshControlDesignable where Self: UITableViewController {

func configureRefreshController() {
guard !isViewLoaded else {
guard isViewLoaded else {
return
}
if hasRefreshControl {
if refreshControl == nil {
refreshControl = UIRefreshControl()
}
refreshControl?.tintColor = refreshControlTintColor
refreshControl?.backgroundColor = refreshControlBackgroundColor

configureRefreshController(hasRefreshControl: hasRefreshControl, refreshControl: &refreshControl)
}

}

public extension RefreshControlDesignable where Self: UITableView {

func configureRefreshController() {
if #available(iOSApplicationExtension 10.0, *) {
configureRefreshController(hasRefreshControl: hasRefreshControl, refreshControl: &refreshControl)
} else {
refreshControl = nil
var refreshControl = self.subviews.first { $0 is UIRefreshControl } as? UIRefreshControl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this automatically? For example, we check there is a UIRefreshControl or not. Add one if not.

Copy link
Member Author

@tbaranes tbaranes Apr 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can, see my answer below!

configureRefreshController(hasRefreshControl: hasRefreshControl, refreshControl: &refreshControl)
}
}

}

fileprivate extension RefreshControlDesignable {

func configureRefreshController(hasRefreshControl: Bool, refreshControl: inout UIRefreshControl?) {
guard hasRefreshControl else {
refreshControl = nil
return
}

if refreshControl == nil {
refreshControl = UIRefreshControl()
}
refreshControl?.tintColor = refreshControlTintColor
refreshControl?.backgroundColor = refreshControlBackgroundColor
}
}