Search code examples
swiftuiviewuikitxibcornerradius

Strange cornerRadius behaviour on UIView from xib


I created a custom Numpad keyboard through xib and wanted to initialize it with a rounded corners.

Here is the code I use:

import UIKit

class NumpadView: UIView {

@IBOutlet weak var resetButton: NumpadButton!
@IBOutlet weak var decimalButton: NumpadButton!

var target: UITextInput?
var view: UIView?

init(target: UITextInput, view: UIView) {
    super.init(frame: .zero)
    self.target = target
    self.view = view
    initializeSubview()
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    initializeSubview()
}

func initializeSubview() {
    let xibFileName = "NumpadView"
    let view = Bundle.main.loadNibNamed(xibFileName, owner: self, options: nil)![0] as! UIView
    self.layer.cornerRadius = 30
    self.layer.masksToBounds = true
    self.addSubview(view)
    view.frame = self.bounds
    self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
}

But then I receive the strange view look in area where cornerRadius is implemented:

How to remove that grey background which is visible near the rounded corners?

UPDATE:

According to View Debugger it seems like this grey layer between yellow square and Visual Effect View is a UICompatibilityInputViewController:

How I presenting the Numpad:

1.I created a NumpadView as a UIView subclass in a xib:

2.In my VC I just change a standard textField.inputView property on my custom NumpadView:

import UIKit

class NumpadViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var textField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()
    setupKeyboardHide()
    textField.delegate = self
    textField.inputView = NumpadView(target: textField, view: view)
}
}

Test project on Github


Solution

  • Another option to get your "rounded corners"...

    Get rid of the Visual Effect View in your Numpad class, and set a layer mask on the superview at run-time.

    In class NumpadView: UIView, UIInputViewAudioFeedback:

    override func layoutSubviews() {
        super.layoutSubviews()
        guard let sv = superview else { return }
        let maskLayer = CAShapeLayer()
        let bez = UIBezierPath(roundedRect: bounds, cornerRadius: 16)
        maskLayer.path = bez.cgPath
        sv.layer.mask = maskLayer
    }
    

    Looks like this:

    enter image description here