Overriding Personalization Screens
If you don’t like a default personalization view controller or you need to make significant changes beyond basic theming and customization, you can override the entire View Controller for a VOPersonalizationOption
and use your own.
If you are using the VOVoucherCreationViewController
and the VOVoucherCreationFlowCoordinator
to launch the create flow, overriding is done by following these steps:
- Create your custom View Controller and make it conform to the
VOPersonalizationOptionViewControllerProtocol
. This is a simple protocol that has an initalizer and aVOPersonalizationOptionViewControllerDelegate
. - Call the
VOPersonalizationOptionViewControllerDelegate
methods for cancel and finish when you dismiss your custom view controller. - Implement the
- (void)personalizationOptionViewController:(UIViewController <VOPersonalizationOptionViewControllerProtocol> *)viewController
personalizationOption:(VOPersonalizationOption *)personalizationOption
selectedPersonalizedObject:(id)selectedPersonalizedObject;
func personalizationOptionViewController(_ viewController: (UIViewController & VOPersonalizationOptionViewControllerProtocol)?, personalizationOption: VOPersonalizationOption?, selectedPersonalizedObject: Any?)
method of the VOVoucherCreationFlowDelegate
and return your custom view controller for the proper VOPersonalizationOption
.
- Optionally implement
- (VOCreationItemView *)creationItemViewForPersonalizationOption:(VOPersonalizationOption *)personalizationOption personalizedObject:(id)personalizedObject;
func creationItemView(for personalizationOption: VOPersonalizationOption?, personalizedObject: Any?) -> VOCreationItemView?
of the VOVoucherCreationFlowDelegate
if you want a custom view dropped into the VOEnvelopeView
.
Example
This is a basic example of overriding the VOTitlePersonalizationOption
.
Step 1 and 2
Create a Custom View Controller, implement VOPersonalizationOptionViewControllerProtocol
and call VOPersonalizationOptionViewControllerDelegate
methods.
#import "SurpriiseTitleViewController.h"
@interface SurpriiseTitleViewController ()
@property (nonatomic, weak) IBOutlet UITextView *addTitleTextView;
@property (nonatomic, weak) IBOutlet UIButton *cancelButton;
@property (nonatomic, weak) IBOutlet UIButton *doneButton;
@property (nonatomic) VOTitlePersonalizationOption *titlePersonalizationOption;
@end
@implementation SurpriiseTitleViewController
#pragma mark - VOPersonalizationOptionViewControllerProtocol
@synthesize delegate;
+ (instancetype)viewControllerWithPersonalizationOption:(VOPersonalizationOption *)personalizationOption
createManager:(VOVoucherCreationManager *)createManager
createFlowDelegate:(id<VOVoucherCreationFlowDelegate>)createFlowDelegate {
SurpriiseTitleViewController *surpriiseTitleViewController = [[SurpriiseTitleViewController alloc] initWithNibName:NSStringFromClass([self class]) bundle:[NSBundle bundleForClass:[self class]]];
surpriiseTitleViewController.titlePersonalizationOption = (VOTitlePersonalizationOption *)personalizationOption;
return surpriiseTitleViewController;
}
#pragma mark - IBActions
- (IBAction)onDone:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
if ([self.delegate respondsToSelector:@selector(personalizationOptionViewController:personalizationOption:selectedPersonalizedObject:)]) {
[self.delegate personalizationOptionViewController:self personalizationOption:self.titlePersonalizationOption selectedPersonalizedObject:@{@"title": self.addTitleTextView.text}];
}
}];
}
- (IBAction)onCancel:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
if ([self.delegate respondsToSelector:@selector(personalizationOptionViewControllerCancelled:)]) {
[self.delegate personalizationOptionViewControllerCancelled:self];
}
}];
}
@end
// SurpriiseTitleViewController.swift
class SurpriiseTitleViewController: UIViewController, VOPersonalizationOptionViewControllerProtocol {
@IBOutlet weak var addTitleTextView: UITextView!
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var doneButton: UIButton!
var delegate: VOPersonalizationOptionViewControllerDelegate!
var titlePersonalizationOption:VOTitlePersonalizationOption?
static func viewController(with personalizationOption: VOPersonalizationOption!, createManager: VOVoucherCreationManager!, createFlowDelegate: VOVoucherCreationFlowDelegate!) -> Self? {
let viewController:SurpriiseTitleViewController = SurpriiseTitleViewController(nibName: NSStringFromClass(self), bundle: Bundle.main);
viewController.titlePersonalizationOption = personalizationOption as? VOTitlePersonalizationOption
return unsafeDowncast(viewController, to: self);
}
@IBAction func onDone(sender: UIButton) {
self.dismiss(animated: true) {
if (self.delegate.responds(to:#selector(PersonalizationOptionViewControllerDelegate.personalizationOptionViewControllerCancelled(_:)))) {
self.delegate.personalizationOptionViewControllerCancelled(self)
}
}
}
@IBAction func onCancel(sender: UIButton) {
self.dismiss(animated: true) {
if (self.delegate.responds(to: #selector(PersonalizationOptionViewControllerDelegate.personalizationOptionViewController(_:personalizationOption:selectedPersonalizedObject:)))) {
self.delegate.personalizationOptionViewController(self, personalizationOption: self.titlePersonalizationOption, selectedPersonalizedObject: ["title": self.addTitleTextView.text])
}
}
}
}
Step 3 and 4
Implement VOVoucherCreationFlowDelegate
methods.
- (nullable UIViewController<VOPersonalizationOptionViewControllerProtocol> *)personalizationViewControllerForPersonalizationOption:(VOPersonalizationOption *)personalizationOption {
if (personalizationOption.type == VOPersonalizationTypeTitle) {
return [SurpriiseTitleViewController viewControllerWithPersonalizationOption:personalizationOption createManager:nil createFlowDelegate:nil];
} else {
return nil;
}
}
- (VOCreationItemView *)creationItemViewForPersonalizationOption:(VOPersonalizationOption *)personalizationOption personalizedObject:(id)personalizedObject {
if (personalizationOption.type == VOPersonalizationTypeTitle) {
// turn a label into a `CreationItemView`
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = personalizedObject[@"title"];
label.backgroundColor = [UIColor redColor];
label.textColor = [UIColor whiteColor];
[label sizeToFit];
VOCreationItemView *itemView = [VOCreationItemView creationItemViewWithType:VOPersonalizationTypeTitle
subType:0
itemId:0
isEditable:YES
isRemovable:YES
viewToRenderAsImage:label
borderWidth:0
borderColor:nil];
CGRect frame = itemView.frame;
frame.size = label.frame.size;
itemView.frame = frame;
return itemView;
} else {
return nil;
}
}
func personalizationViewController(for personalizationOption: VOPersonalizationOption?) -> (UIViewController & VOPersonalizationOptionViewControllerProtocol)? {
if (personalizationOption.type == VOPersonalizationTypeTitle) {
return SurpriiseTitleViewController(personalizationOption: personalizationOption, createManager: nil, createFlowDelegate: nil)!
} else {
return nil
}
}
func creationItemView(for personalizationOption: VOPersonalizationOption?, personalizedObject: Any?) -> VOCreationItemView? {
if personalizationOption.type == VOPersonalizationTypeTitle {
// turn a label into a `CreationItemView`
let label = UILabel(frame: CGRect.zero)
label.text = (personalizedObject as! Dictionary)["title"]
label.backgroundColor = UIColor.red
label.textColor = UIColor.white
label.sizeToFit()
let itemView = VOCreationItemView.init(type: VOPersonalizationTypeTitle, subType: 0, itemId: 0, isEditable: true, isRemovable: true, viewToRenderAsImage:label, borderWidth: 0, borderColor: nil)
itemView?.frame.size = label.frame.size
return itemView
} else {
return nil
}
}