SF Symbols are designed to be used more like a font character - with "padding" on the sides - so we need to "remove" that padding.
Here is one approach by sub-classing UIImageView
:
class FlagImageView: UIImageView {
override func layoutSubviews() {
super.layoutSubviews()
let nm = "flag.circle.fill"
// create SF Symbol image with point size equal to bounds height
let cfg = UIImage.SymbolConfiguration(pointSize: bounds.height)
guard let imgA = UIImage(systemName: nm, withConfiguration: cfg) else {
fatalError("Could not load SF Symbol: \(nm)!")
}
// get a cgRef from imgA
guard let cgRef = imgA.cgImage else {
fatalError("Could not get cgImage!")
}
// create imgB from the cgRef
// this will remove the "padding"
let imgB = UIImage(cgImage: cgRef, scale: imgA.scale, orientation: imgA.imageOrientation)
.withTintColor(.white, renderingMode: .alwaysOriginal)
self.image = imgB
// add a round mask, inset by 1.0 so we don't see the anti-aliased edge
let msk = CAShapeLayer()
msk.path = UIBezierPath(ovalIn: bounds.insetBy(dx: 1.0, dy: 1.0)).cgPath
layer.mask = msk
}
}
Example view controller:
class FlagVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
let greenView = UIView()
greenView.backgroundColor = .systemGreen
let flagView = FlagImageView(frame: .zero)
flagView.backgroundColor = .red
greenView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(greenView)
flagView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(flagView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
greenView.topAnchor.constraint(equalTo: g.topAnchor, constant: 80.0),
greenView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 100.0),
greenView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
greenView.heightAnchor.constraint(equalToConstant: 80.0),
flagView.topAnchor.constraint(equalTo: greenView.topAnchor, constant: 8.0),
flagView.leadingAnchor.constraint(equalTo: greenView.leadingAnchor, constant: -12.0),
flagView.widthAnchor.constraint(equalToConstant: 40.0),
flagView.heightAnchor.constraint(equalTo: flagView.widthAnchor),
])
greenView.layer.cornerRadius = 40.0
}
}
Result:

There is a detailed explanation about SF Symbol usage here: https://stackoverflow.com/a/71743787/6257435