Skip to content

Commit

Permalink
Version 2.1: Change checkout preferences
Browse files Browse the repository at this point in the history
* [ADDED] Provide method to let merchants change their checkout preferences
  `+[SumupSDK presentCheckoutPreferencesFromViewController:animated:completion:]`

Sample application:

* [ADDED] Add button to present checkout preferences
* [BUGFIX] Add missing `-ObjC` linker flag to Swift sample app
  • Loading branch information
mollidor committed Feb 2, 2017
2 parents 92bbb90 + 013e01a commit 0b68d2c
Show file tree
Hide file tree
Showing 142 changed files with 196 additions and 59 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# SumUp iOS SDK Changelog

## Version 2.1

* [ADDED] Provide method to let merchants change their checkout preferences
`+[SumupSDK presentCheckoutPreferencesFromViewController:animated:completion:]`

Sample application:

* [ADDED] Add button to present checkout preferences
* [BUGFIX] Add missing `-ObjC` linker flag to Swift sample app


## Version 2.0

* [IMPROVEMENT] Support latest Air and Air Lite terminals
Expand Down
52 changes: 38 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
[![Platform](https://img.shields.io/badge/Platform-iOS-lightgrey.svg?style=flat-square)](#prerequisites)
[![Created](https://img.shields.io/badge/Made%20by-SumUp-blue.svg?style=flat-square)]()
[![Supports](https://img.shields.io/badge/Requires-iOS%206+-red.svg?style=flat-square)]()
[![Version](https://img.shields.io/badge/Version-2.0-yellowgreen.svg?style=flat-square)](CHANGELOG.md)
[![Licence](https://img.shields.io/badge/Licence-SumUp-brightgreen.svg?style=flat-square)](LICENCE)
[![Version](https://img.shields.io/badge/Version-2.1-yellowgreen.svg?style=flat-square)](CHANGELOG.md)
[![License](https://img.shields.io/badge/License-SumUp-brightgreen.svg?style=flat-square)](LICENSE)


This repository provides a native iOS SDK that enables you to integrate SumUp's proprietary
card terminal(s) and its payment platform to accept credit and debit card payments
Expand All @@ -24,11 +25,11 @@ For more information, please refer to SumUp's

### Prerequisites
1. Registered for a merchant account via SumUp's [country websites](https://sumup.com/) (or received a test account).
2. Received SumUp card terminal: Air, Air Lite, PIN+ Terminal, Chip/Magstripe or Signature Card Reader.
2. Received SumUp card terminal: Air, Air Lite, PIN+ terminal or Chip & Signature reader.
3. Requested an Affiliate (Access) Key via [SumUp Dashboard](https://me.sumup.com/developers) for Developers.
4. Deployment Target iOS 6.0 or later.
5. Xcode 7 and iOS SDK 9 or later.
6. iPhone, iPad or iPod touch of all sizes and resolutions running on iOS 6+.
6. iPhone, iPad or iPod touch.

### Table of Contents
* [Installation](#installation)
Expand All @@ -39,6 +40,7 @@ For more information, please refer to SumUp's
* [Authenticate app](#authenticate-app)
* [Login](#login)
* [Accept card payments](#accept-card-payments)
* [Update checkout preferences](#update-checkout-preferences)
* [Community](#community)
* [Changelog](#changelog)
* [License](#license)
Expand All @@ -51,27 +53,29 @@ The SumUp SDK is provided as an embedded framework `SumupSDK.embeddedframework`
that combines a static library, its headers and bundles containing resources such as
images and localizations. Please follow the steps below to prepare your project:

1. Add the `SumupSDK.embeddedframework` to your Xcode project (e.g. in the group Frameworks).
Please ensure that the following frameworks are part of your app's target:

SumupSDK.embeddedframework/SumupSDK.framework
SumupSDK.embeddedframework/Reources/SMPSharedResources.bundle
SumupSDK.embeddedframework/Resources/YTLibResources.bundle

2. Link your app to `SumupSDK.framework`.
1. Add the `SumupSDK.embeddedframework` to your Xcode project.
2. Link your app against `SumupSDK.framework`.
3. Link your app against the following system frameworks:

AVFoundation
Accelerate
AVFoundation
MapKit

4. Add `-ObjC` to "Other Linker Flags" if not yet included.

5. Add the bundles provided in `SumupSDK.embeddedframework/Resources`
to your app target.

SumupSDK.embeddedframework/Resources/SMPSharedResources.bundle
SumupSDK.embeddedframework/Resources/YTLibResources.bundle


> Note:
> You can use the [sample app](https://github.com/sumup/sumup-ios-sdk/tree/master/SumupSDKSampleApp)
that is provided with the SumUp SDK as a reference project. The Xcode project contains sample apps
written in Objective-C and Swift.


### Supported device orientation
The SDK supports all device orientations on iPad and portrait on iPhone.
Feel free to support other orientations on iPhone but please keep in mind that
Expand Down Expand Up @@ -105,7 +109,7 @@ and [microphone access in iOS 7 and later](https://developer.apple.com/library/i

## Getting started
### Authenticate app
Before calling any additional feature of the SumUp SDK, you are required to setup the SDK with your Affiliate (Access) Key:
Before calling any additional feature of the SumUp SDK, you are required to set up the SDK with your Affiliate (Access) Key:
```objc
#import <SumupSDK/SumupSDK.h>

Expand Down Expand Up @@ -179,6 +183,26 @@ Start a payment by using the checkout request below:
}];
```

### Update checkout preferences
When logged in you can let merchants check and update their checkout
preferences. Merchants can select their preferred card terminal and set up a
new one if needed. The preferences available to a merchant depend on their
respective account settings.

```objc
[SumupSDK presentCheckoutPreferencesFromViewController:self
animated:YES
completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
// there was a problem presenting the preferences
} else {
// next checkout will reflect the merchant's changes.
}
}];
}
```
## Community
- **Questions?** Get in contact with our integration team by sending an email to
<a href="mailto:[email protected]">[email protected]</a>.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,23 @@ typedef void (^SMPCheckoutCompletionBlock)(SMPCheckoutResult * _Nullable result
*/
+ (BOOL)checkoutInProgress;


/**
* Presenting checkout preferences allows the current merchant to configure the checkout options and
* change the card terminal. Merchants can also set up the terminal when applicable.
* Can only be called when a merchant is logged in and checkout is not in progress.
* The completion block will be executed once the preferences have been dismissed.
* The success parameter indicates whether the preferences have been presented.
* If not successful an error will be provided, see SMPSumupSDKError.
*
* @param fromViewController The UIViewController instance from which the checkout should be presented modally.
* @param animated Pass YES to animate the transition.
* @param block The completion block is called after the view controller has been dismissed.
*/
+ (void)presentCheckoutPreferencesFromViewController:(UIViewController *)fromViewController
animated:(BOOL)animated
completion:(nullable SumupCompletionBlock)block;

/**
Performs a logout of the current merchant and resets the remembered password.
\param block The completion block is called once the logout has finished.
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
18 changes: 9 additions & 9 deletions SumupSDKSampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1B584F461DE6132D00642029 /* MapKit.framework in Frameworks */,
1B584F451DE6132700642029 /* AVFoundation.framework in Frameworks */,
1B584F441DE6131E00642029 /* Accelerate.framework in Frameworks */,
1B584F411DE6130600642029 /* SumupSDK.framework in Frameworks */,
1B584F441DE6131E00642029 /* Accelerate.framework in Frameworks */,
1B584F451DE6132700642029 /* AVFoundation.framework in Frameworks */,
1B584F461DE6132D00642029 /* MapKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -77,8 +77,8 @@
buildActionMask = 2147483647;
files = (
DC9610EE18996388009D8EBC /* SumupSDK.framework in Frameworks */,
DCA9F47F189968C70057702B /* AVFoundation.framework in Frameworks */,
E92050D81B289E4B00173579 /* Accelerate.framework in Frameworks */,
DCA9F47F189968C70057702B /* AVFoundation.framework in Frameworks */,
DCA9F4771899687D0057702B /* MapKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -275,9 +275,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1B584F431DE6130D00642029 /* SMPSharedResources.bundle in Resources */,
1B584F421DE6130A00642029 /* YTLibResources.bundle in Resources */,
1B584F491DE6146000642029 /* Main-Swift.storyboard in Resources */,
1B584F431DE6130D00642029 /* SMPSharedResources.bundle in Resources */,
1B584F3F1DE6124400642029 /* Launch Screen.storyboard in Resources */,
1B584F401DE6125100642029 /* InfoPlist.strings in Resources */,
1B584F3D1DE6123300642029 /* Images.xcassets in Resources */,
Expand All @@ -288,12 +288,12 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E93AF477192BAB2A00AD09AC /* YTLibResources.bundle in Resources */,
DC9610ED18996388009D8EBC /* SMPSharedResources.bundle in Resources */,
1BF7553B1CF6093C00C793FB /* Launch Screen.storyboard in Resources */,
DC9610CD18996359009D8EBC /* Images.xcassets in Resources */,
DC9610C818996359009D8EBC /* Main-ObjC.storyboard in Resources */,
DC9610BF18996359009D8EBC /* InfoPlist.strings in Resources */,
E93AF477192BAB2A00AD09AC /* YTLibResources.bundle in Resources */,
DC9610ED18996388009D8EBC /* SMPSharedResources.bundle in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -444,7 +444,6 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_VERSION = 3.0.1;
Expand Down Expand Up @@ -485,7 +484,6 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 3.0.1;
Expand All @@ -502,6 +500,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "SumupSDKSampleApp/SrcObjC/SumupSDKSampleApp-Prefix.pch";
INFOPLIST_FILE = "SumupSDKSampleApp/SumupSDKSampleApp-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.sumup.sample-objc";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand All @@ -520,6 +519,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "SumupSDKSampleApp/SrcObjC/SumupSDKSampleApp-Prefix.pch";
INFOPLIST_FILE = "SumupSDKSampleApp/SumupSDKSampleApp-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.sumup.sample-objc";
PRODUCT_NAME = "$(TARGET_NAME)";
Expand Down
4 changes: 2 additions & 2 deletions SumupSDKSampleApp/Launch Screen.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="15G1108" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="NO" initialViewController="01J-lp-oVM">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G1212" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies>
<development version="7000" identifier="xcode"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
</dependencies>
<scenes>
Expand Down
22 changes: 20 additions & 2 deletions SumupSDKSampleApp/SrcObjC/SUSViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ @interface SUSViewController () <UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UIButton *buttonLogin;
@property (weak, nonatomic) IBOutlet UIButton *buttonLogout;
@property (weak, nonatomic) IBOutlet UIButton *buttonCharge;
@property (weak, nonatomic) IBOutlet UIButton *buttonPreferences;

@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UILabel *versionLabel;
Expand Down Expand Up @@ -48,6 +49,16 @@ - (IBAction)buttonLoginTapped:(id)sender {
}];
}

- (IBAction)buttonOpenPreferencesTapped:(id)sender {
[SumupSDK presentCheckoutPreferencesFromViewController:self
animated:YES
completion:^(BOOL success, NSError * _Nullable error) {
if (!success || error) {
[self showResultsString:@"not logged in"];
}
}];
}

- (IBAction)buttonChargeTapped:(id)sender {
// check total and currency code
NSString *total = [[self textFieldTotal] text];
Expand Down Expand Up @@ -98,7 +109,14 @@ - (void)updateButtonState {
BOOL isLoggedIn = [SumupSDK isLoggedIn];
[[self buttonLogin] setEnabled:!isLoggedIn];
[[self buttonLogout] setEnabled:isLoggedIn];

// real apps should usually disable these actions when the user
// is not logged in - we keep them enabled to demonstrate the
// error handling

// [[self buttonCharge] setEnabled:isLoggedIn];
// [[self buttonPreferences] setEnabled:isLoggedIn];

[self addCurrencyToTextField];
}

Expand Down Expand Up @@ -129,13 +147,13 @@ - (void)showResultsString:(NSString *)result {
[self.label setText:result];
[UIView animateWithDuration:1.5
delay:0
options:UIViewAnimationOptionAllowUserInteraction
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState
animations:^{
[self.label setAlpha:1.0];
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5
delay:2.0
options:UIViewAnimationOptionAllowUserInteraction
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState
animations:^{
[self.label setAlpha:0.0];
} completion:nil];
Expand Down
51 changes: 43 additions & 8 deletions SumupSDKSampleApp/SrcSwift/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class ViewController: UIViewController {

@IBOutlet fileprivate weak var buttonLogin: UIButton?
@IBOutlet fileprivate weak var buttonLogout: UIButton?
@IBOutlet private weak var buttonCharge: UIButton?
@IBOutlet fileprivate weak var buttonPreferences: UIButton?
@IBOutlet fileprivate weak var buttonCharge: UIButton?

@IBOutlet fileprivate weak var textFieldTotal: UITextField?
@IBOutlet fileprivate weak var textFieldTitle: UITextField?
Expand All @@ -39,29 +40,58 @@ class ViewController: UIViewController {

if !appearCompleted {
appearCompleted = true
presentLogin(animated: true)
presentLogin()
}
}

// MARK: - Storyboard Actions

@IBAction private func buttonLoginTapped(_ sender: Any) {
presentLogin(animated: true)
presentLogin()
}

@IBAction private func buttonLogoutTapped(_ sender: Any) {
requestLogout()
}

@IBAction private func buttonOpenPreferencesTapped(_ sender: Any) {
presentCheckoutPreferences()
}

@IBAction private func buttonChargeTapped(_ sender: Any) {
requestCheckout()
}

// MARK: - SumupSDK interactions

private func presentLogin(animated: Bool) {
private func presentCheckoutPreferences() {
SumupSDK.presentCheckoutPreferences(from: self, animated: true) { [weak self] (success: Bool, presentationError: Error?) in
guard let safeError = presentationError as? NSError else {
// no error, nothing else to do
return
}

print("error presenting checkout preferences: \(safeError)")

let errorMessage: String
switch (safeError.domain, safeError.code) {
case (SMPSumupSDKErrorDomain, SMPSumupSDKError.accountNotLoggedIn.rawValue):
errorMessage = "not logged in"

case (SMPSumupSDKErrorDomain, SMPSumupSDKError.checkoutInProgress.rawValue):
errorMessage = "checkout is in progress"

default:
errorMessage = "general error"
}

self?.showResult(string: errorMessage)
}
}

private func presentLogin() {
// present login UI and wait for completion block to update button states
SumupSDK.presentLogin(from: self, animated: animated) { [weak self] (success: Bool, error: Error?) in
SumupSDK.presentLogin(from: self, animated: true) { [weak self] (success: Bool, error: Error?) in
guard error == nil else {
// errors are handled within the SDK, there should be no need
// for your app to display any error message
Expand Down Expand Up @@ -153,8 +183,13 @@ extension ViewController {
let isLoggedIn = SumupSDK.isLoggedIn()
buttonLogin?.isEnabled = !isLoggedIn
buttonLogout?.isEnabled = isLoggedIn
// in this sample app we leave the charge button enabled
// to highlight the error handling in buttonChargeTapped(_)

// real apps should usually disable these actions when the user
// is not logged in - we keep them enabled to demonstrate the
// error handling

// buttonCharge?.isEnabled = isLoggedIn
// buttonPreferences?.isEnabled = isLoggedIn
}

fileprivate func applyStyle() {
Expand Down Expand Up @@ -192,7 +227,7 @@ extension ViewController {
fileprivate func showResult(string: String) {
label?.text = string
// fade in label
UIView.animateKeyframes(withDuration: 3, delay: 0, options: .allowUserInteraction, animations: {
UIView.animateKeyframes(withDuration: 3, delay: 0, options: [.allowUserInteraction, .beginFromCurrentState], animations: {
let relativeDuration = TimeInterval(0.15)
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: relativeDuration) {
self.label?.alpha = 1.0
Expand Down
Loading

0 comments on commit 0b68d2c

Please sign in to comment.