# Customize the Frames iOS SDK > **Note** > > Frames will be deprecated on June 30, 2026. [Upgrade to Flow for mobile](https://www.checkout.com/docs/payments/accept-payments/upgrade-to-flow-from-frames/upgrade-from-frames-for-ios.md), our pre-built, customizable payment user interface. Flow provides a more flexible, scalable, and feature-rich integration, as well as access to additional payment methods. When a customer initiates a payment with the Frames iOS SDK, their payment information is collected via two customizable forms: - Payment Form: prompts users for their payment card details - Billing Form: prompts users for their billing information The styling of these forms can be customized through the use of the `paymentFormStyle` and `billingFormStyle` objects, which are wrapped in the `PaymentStyle` wrapper. ```swift PaymentStyle(paymentFormStyle: YourPaymentStyle(), billingFormStyle: YourBillingStyle()) ``` You can choose between three different options for customization, depending on how much control you need over the forms' UI design. In order of increasing complexity these are: - [Default](#Default_form) - [Themed](#Themed_form) - [Custom](#Custom_form) --- ## Default form The default integration is the quickest way to display the forms required to collect payment information, with no additional customization required. Localization support for the following languages is built into the default integration: - Arabic - Dutch - English - French - German - Italian - Romanian - Spanish You can also add your own localized strings to add support for additional languages. For basic customization, the `DefaultPaymentFormStyle` and `DefaultBillingFormStyle` objects expose properties that allow you to change the text and colors displayed on the forms. ```swift // Create a new DefaultPaymentFormStyle object var paymentFormStyle = DefaultPaymentFormStyle() // Change the payment form's background color paymentFormStyle.backgroundColor = UIColor.darkGray // Change the card number field's placeholder value paymentFormStyle.expiryDate.textfield.placeholder = "00 / 00" // Change the payment button text paymentFormStyle.payButton.text = "Pay £54.63" // Create a new DefaultBillingFormStyle object var billingFormStyle = DefaultBillingFormStyle() // Change the billing form header's font color billingFormStyle.header.headerLabel.textColor = UIColor.darkGray // Change the billing form header text paymentFormStyle.header.headerLabel.text = "Billing info" // Wrap the styling in a PaymentStyle wrapper let paymentStyle = PaymentStyle(paymentFormStyle: paymentFormStyle, billingFormStyle: billingFormStyle) ``` See [our example project on GitHub](https://github.com/checkout/frames-ios/blob/main/iOS%20Example%20Frame/iOS%20Example%20Frame/Factory/Factory.swift#L68:L93). --- ## Themed form If you want to customize your forms beyond what is supported by the default integration, you can apply a theme using the `Theme` object. When instantiating a new `Theme` object, you must supply the following fields at a minimum: - `primaryFontColor` - `secondaryFontColor` - `buttonFontColor` - `errorFontColor` - `backgroundColor` - `errorBorderColor` You can then optionally provide additional values to customize other elements including button styling, custom placeholder and error text, and field input controls. Dynamic font sizing based on the user's device is built-in to the `Theme` object. ```swift // Create a new Theme object var theme = Theme(primaryFontColor: UIColor(red: 0 / 255, green: 204 / 255, blue: 45 / 255, alpha: 1), secondaryFontColor: UIColor(red: 177 / 255, green: 177 / 255, blue: 177 / 255, alpha: 1), buttonFontColor: .green, errorFontColor: .red, backgroundColor: UIColor(red: 23 / 255, green: 32 / 255, blue: 30 / 255, alpha: 1), errorBorderColor: .red) // Add a border and corner radius around text input fields theme.textInputBackgroundColor = UIColor(red: 36 / 255.0, green: 48 / 255.0, blue: 45 / 255.0, alpha: 1.0) theme.textInputBorderRadius = 4 // Add a border around input sections theme.borderRadius = 4 // Create a new payment form style, only providing custom text values var paymentFormStyle = theme.buildPaymentForm( headerView: theme.buildPaymentHeader(title: "Payment details", subtitle: "Accepting your favorite payment methods"), addBillingButton: theme.buildAddBillingSectionButton(text: "Add billing details", isBillingAddressMandatory: false, titleText: "Billing details"), billingSummary: theme.buildBillingSummary(buttonText: "Change billing details", titleText: "Billing details"), cardNumber: theme.buildPaymentInput(isTextFieldNumericInput: true, titleText: "Card number", errorText: "Please enter valid card number"), expiryDate: theme.buildPaymentInput(textFieldPlaceholder: "__ / __", isTextFieldNumericInput: false, titleText: "Expiry date", errorText: "Please enter valid expiry date"), securityCode: theme.buildPaymentInput(isTextFieldNumericInput: true, titleText: "CVV date", errorText: "Please enter valid security code"), payButton: theme.buildPayButton(text: "Pay now")) // Override a custom property from the resulting payment form style paymentFormStyle.payButton.disabledTextColor = UIColor.lightGray // Create a new billing form style, and modify each field's properties individually var billingFormStyle = theme.buildBillingForm( header: theme.buildBillingHeader(title: "Billing information", cancelButtonTitle: "Cancel", doneButtonTitle: "Done"), cells: [.fullName(theme.buildBillingInput(text: "", isNumericInput: false, isMandatory: false, title: "Your name")), .addressLine1(theme.buildBillingInput(text: "", isNumericInput: false, isMandatory: true, title: "Address")), .city(theme.buildBillingInput(text: "", isNumericInput: false, isMandatory: true, title: "City")), .country(theme.buildBillingCountryInput(buttonText: "Select your country", title: "Country")), .phoneNumber(theme.buildBillingInput(text: "", isNumericInput: true, isMandatory: true, title: "Phone number"))]) ``` See [our example project on GitHub](https://github.com/checkout/frames-ios/blob/main/iOS%20Example%20Frame/iOS%20Example%20Frame/Style/ThemeDemo.swift). --- ## Custom form For complete control over how the various UI elements on your forms look, you can use the fully custom solution. You can use the properties listed in the `structs` below to edit each individual UI component displayed across the forms: ```swift private enum Constants { static let mainFontColor = UIColor(red: 0 / 255, green: 204 / 255, blue: 45 / 255, alpha: 1) static let secondaryFontColor = UIColor(red: 177 / 255, green: 177 / 255, blue: 177 / 255, alpha: 1) static let errorColor = UIColor.red static let backgroundColor = UIColor(red: 23 / 255, green: 32 / 255, blue: 30 / 255, alpha: 1) static let textFieldBackgroundColor = UIColor(red: 36 / 255.0, green: 48 / 255.0, blue: 45 / 255.0, alpha: 1.0) static let borderRadius: CGFloat = 4 static let borderWidth: CGFloat = 1 } // Main payment form struct PaymentFormStyleCustom1: PaymentFormStyle { var backgroundColor: UIColor = Constants.backgroundColor var headerView: PaymentHeaderCellStyle = StyleOrganiser.PaymentHeaderViewStyle() var addBillingSummary: CellButtonStyle? = StyleOrganiser.BillingStartButton() var editBillingSummary: BillingSummaryViewStyle? = StyleOrganiser.BillingSummaryStyle() var cardholderInput: CellTextFieldStyle? var cardNumber: CellTextFieldStyle = StyleOrganiser.CardNumberSection() var expiryDate: CellTextFieldStyle = StyleOrganiser.ExpiryDateSection() var securityCode: CellTextFieldStyle? = StyleOrganiser.SecurityNumberSection() var payButton: ElementButtonStyle = StyleOrganiser.PayButtonFormStyleCustom1() } struct BillingFormStyleCustom1: BillingFormStyle { var mainBackground: UIColor = Constants.backgroundColor var header: BillingFormHeaderCellStyle = StyleOrganiser.BillingHeaderViewStyle() var cells: [BillingFormCell] = [ .fullName(StyleOrganiser.BillingFullNameInput()), .addressLine1(StyleOrganiser.BillingAddressLine1Input()), .addressLine2(StyleOrganiser.BillingAddressLine2Input()), .city(StyleOrganiser.BillingCityInput()), .state(StyleOrganiser.BillingStateInput()), .postcode(StyleOrganiser.BillingPostcodeInput()), .country(StyleOrganiser.BillingCountryInput()), .phoneNumber(StyleOrganiser.BillingPhoneInput()) ] } private enum StyleOrganiser { struct PaymentHeaderViewStyle: PaymentHeaderCellStyle { var shouldHideAcceptedCardsList = true var backgroundColor: UIColor = Constants.backgroundColor var headerLabel: ElementStyle? = PaymentHeaderLabel() var subtitleLabel: ElementStyle? = PaymentHeaderSubtitle() var schemeIcons: [UIImage?] = [] } struct BillingHeaderViewStyle: BillingFormHeaderCellStyle { var backgroundColor: UIColor = .clear var headerLabel: ElementStyle = BillingHeaderLabel() var cancelButton: ElementButtonStyle = CancelButtonStyle() var doneButton: ElementButtonStyle = DoneButtonStyle() } struct BillingHeaderLabel: ElementStyle { var textAlignment: NSTextAlignment = .natural var isHidden = false var text: String = "Billing address" var font = UIFont(sfMono: .semibold, size: 24) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct PayButtonFormStyleCustom1: ElementButtonStyle { var image: UIImage? var textAlignment: NSTextAlignment = .center var text: String = "Pay 100$" var font = UIFont.systemFont(ofSize: 15) var disabledTextColor: UIColor = Constants.secondaryFontColor var disabledTintColor: UIColor = Constants.mainFontColor.withAlphaComponent(0.2) var activeTintColor: UIColor = Constants.mainFontColor var backgroundColor: UIColor = Constants.mainFontColor var textColor: UIColor = .white var normalBorderColor: UIColor = .clear var focusBorderColor: UIColor = .clear var errorBorderColor: UIColor = .clear var imageTintColor: UIColor = .clear var isHidden = false var isEnabled = true var height: Double = 56 var width: Double = 0 var cornerRadius: CGFloat = 10 var borderWidth: CGFloat = 0 var textLeading: CGFloat = 0 } struct CancelButtonStyle: ElementButtonStyle { var textAlignment: NSTextAlignment = .natural var isEnabled = true var disabledTextColor: UIColor = Constants.secondaryFontColor var disabledTintColor: UIColor = .clear var activeTintColor: UIColor = .clear var imageTintColor: UIColor = .clear var normalBorderColor: UIColor = .clear var focusBorderColor: UIColor = .clear var errorBorderColor: UIColor = .clear var image: UIImage? var textLeading: CGFloat = 0 var cornerRadius: CGFloat = Constants.borderRadius var borderWidth: CGFloat = Constants.borderWidth var height: Double = 60 var width: Double = 70 var isHidden = false var text: String = "Cancel" var font = UIFont(sfMono: .semibold, size: 17) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct DoneButtonStyle: ElementButtonStyle { var textAlignment: NSTextAlignment = .natural var isEnabled = true var disabledTextColor: UIColor = Constants.secondaryFontColor var disabledTintColor: UIColor = .clear var activeTintColor: UIColor = .clear var imageTintColor: UIColor = .clear var normalBorderColor: UIColor = .clear var focusBorderColor: UIColor = .clear var errorBorderColor: UIColor = .clear var image: UIImage? var textLeading: CGFloat = 0 var cornerRadius: CGFloat = Constants.borderRadius var borderWidth: CGFloat = Constants.borderWidth var height: Double = 60 var width: Double = 70 var isHidden = false var text: String = "Done" var font = UIFont(sfMono: .semibold, size: 17) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct PaymentHeaderLabel: ElementStyle { var textAlignment: NSTextAlignment = .natural var isHidden = false var text: String = "Payment details" var font = UIFont(size: 24) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct PaymentHeaderSubtitle: ElementStyle { var textAlignment: NSTextAlignment = .natural var isHidden = false var text: String = "Visa, Mastercard and Maestro accepted." var font = UIFont(size: 12) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct CardNumberSection: CellTextFieldStyle { var isMandatory = true var backgroundColor: UIColor = .clear var textfield: ElementTextFieldStyle = TextFieldStyle() var title: ElementStyle? = TitleStyle(text: "Card number") var mandatory: ElementStyle? = MandatoryStyle(text: "") var hint: ElementStyle? var error: ElementErrorViewStyle? = ErrorViewStyle(text: "Insert a valid card number") } struct ExpiryDateSection: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(placeholder: "_ _ / _ _") var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Expiry date") var mandatory: ElementStyle? = MandatoryStyle(text: "") var hint: ElementStyle? var error: ElementErrorViewStyle? = ErrorViewStyle(text: "Insert a valid expiry date") } struct SecurityNumberSection: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle() var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Security code") var mandatory: ElementStyle? = MandatoryStyle(text: "") var hint: ElementStyle? var error: ElementErrorViewStyle? = ErrorViewStyle(text: "Insert a valid security code") } struct TextFieldStyle: ElementTextFieldStyle { var textAlignment: NSTextAlignment = .natural var text: String = "" var isSupportingNumericKeyboard = true var height: Double = 56 var cornerRadius: CGFloat = Constants.borderRadius var borderWidth: CGFloat = Constants.borderWidth var placeholder: String? var tintColor: UIColor = Constants.mainFontColor var normalBorderColor: UIColor = .clear var focusBorderColor: UIColor = .clear var errorBorderColor: UIColor = Constants.errorColor var isHidden = false var font = UIFont(size: 15) var backgroundColor: UIColor = Constants.textFieldBackgroundColor var textColor: UIColor = Constants.mainFontColor } struct TitleStyle: ElementStyle { var textAlignment: NSTextAlignment = .natural var text: String var isHidden = false var font = UIFont(size: 15) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct MandatoryStyle: ElementStyle { var textAlignment: NSTextAlignment = .natural var text: String var isHidden = false var font = UIFont(size: 13) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.secondaryFontColor } struct SubtitleElementStyle: ElementStyle { var textAlignment: NSTextAlignment = .natural var text: String var textColor: UIColor = Constants.secondaryFontColor var backgroundColor: UIColor = .clear var tintColor: UIColor = Constants.mainFontColor var image: UIImage? var height: Double = 30 var isHidden = false var font = UIFont(size: 13) } struct ErrorViewStyle: ElementErrorViewStyle { var textAlignment: NSTextAlignment = .natural var text: String var textColor: UIColor = Constants.errorColor var backgroundColor: UIColor = .clear var tintColor: UIColor = Constants.errorColor var image: UIImage? var height: Double = 30 var isHidden = true var font = UIFont(size: 13) } struct BillingStartButton: CellButtonStyle { var isMandatory = true var button: ElementButtonStyle = AddBillingDetailsButtonStyle() var backgroundColor: UIColor = .red// .clear var title: ElementStyle? = TitleStyle(text: "Billing address") var mandatory: ElementStyle? var hint: ElementStyle? = { var element = SubtitleElementStyle(text: "We need this information as an additional security measure to verify this card.") element.textColor = Constants.mainFontColor return element }() var error: ElementErrorViewStyle? } struct BillingSummaryStyle: BillingSummaryViewStyle { var summary: ElementStyle? = BillingSummaryElementStyle(text: "") var cornerRadius: CGFloat = Constants.borderRadius var borderWidth: CGFloat = Constants.borderWidth var separatorLineColor: UIColor = Constants.secondaryFontColor var borderColor: UIColor = Constants.mainFontColor var button: ElementButtonStyle = AddBillingDetailsButtonStyle(textLeading: 20, text: "\u{276F} Update Billing Address") var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Billing address") var mandatory: ElementStyle? var hint: ElementStyle? = { var element = SubtitleElementStyle(text: "We need this information as an additional security measure to verify this card.") element.textColor = Constants.mainFontColor return element }() var error: ElementErrorViewStyle? } struct AddBillingDetailsButtonStyle: ElementButtonStyle { var textAlignment: NSTextAlignment = .natural var isEnabled = true var disabledTextColor: UIColor = Constants.secondaryFontColor var disabledTintColor: UIColor = Constants.secondaryFontColor var activeTintColor: UIColor = Constants.mainFontColor var imageTintColor: UIColor = .clear var normalBorderColor: UIColor = .clear var focusBorderColor: UIColor = .clear var errorBorderColor: UIColor = .clear var image: UIImage? var textLeading: CGFloat = 0 var cornerRadius: CGFloat = 0 var borderWidth: CGFloat = 0 var height: Double = 56 var width: Double = 300 var isHidden = false var text: String = "\u{276F} Add billing address" var font = UIFont(sfMono: .semibold, size: 15) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.mainFontColor } struct BillingFullNameInput: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(isSupportingNumericKeyboard: false) var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Full name") var mandatory: ElementStyle? var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingAddressLine1Input: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(isSupportingNumericKeyboard: false) var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Address line 1") var mandatory: ElementStyle? var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingAddressLine2Input: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(isSupportingNumericKeyboard: false) var isMandatory = false var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Address line 2") var mandatory: ElementStyle? = MandatoryStyle(text: "Optional") var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingCityInput: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(isSupportingNumericKeyboard: false) var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "City") var mandatory: ElementStyle? var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingStateInput: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(isSupportingNumericKeyboard: false) var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "State") var mandatory: ElementStyle? var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingPostcodeInput: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle(isSupportingNumericKeyboard: false) var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Postcode/Zip") var mandatory: ElementStyle? var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingCountryInput: CellButtonStyle { var button: ElementButtonStyle = BillingCountryButton() var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Country") var mandatory: ElementStyle? var hint: ElementStyle? var error: ElementErrorViewStyle? } struct BillingPhoneInput: CellTextFieldStyle { var textfield: ElementTextFieldStyle = TextFieldStyle() var isMandatory = true var backgroundColor: UIColor = .clear var title: ElementStyle? = TitleStyle(text: "Phone number") var mandatory: ElementStyle? var hint: ElementStyle? = SubtitleElementStyle(text: "We will only use this to confirm identity if necessary") var error: ElementErrorViewStyle? } struct BillingSummaryElementStyle: ElementStyle { var textAlignment: NSTextAlignment = .natural var isHidden = false var text: String var font = UIFont(size: 14) var backgroundColor: UIColor = .clear var textColor: UIColor = Constants.secondaryFontColor } struct BillingCountryButton: ElementButtonStyle { var textAlignment: NSTextAlignment = .natural var isEnabled = true var disabledTextColor: UIColor = Constants.secondaryFontColor var disabledTintColor: UIColor = .clear var activeTintColor: UIColor = Constants.mainFontColor var imageTintColor: UIColor = Constants.mainFontColor var normalBorderColor: UIColor = .clear var focusBorderColor: UIColor = .clear var errorBorderColor: UIColor = .clear var image: UIImage? = UIImage(named: "arrow_green_down") var textLeading: CGFloat = 20 var cornerRadius: CGFloat = Constants.borderRadius var borderWidth: CGFloat = 0 var height: Double = 20 var width: Double = 80 var isHidden = false var text: String = "Please select a country" var font = UIFont(size: 15) var backgroundColor: UIColor = Constants.textFieldBackgroundColor var textColor: UIColor = Constants.secondaryFontColor } } ``` See an example on [our GitHub project](https://github.com/checkout/frames-ios/blob/main/iOS%20Example%20Frame/iOS%20Example%20Frame/Style/CustomStyle1.swift).