How to make custom rounded UIImageView subclass? - swift

I want to make my custom round UIImageView and show it in storyboard.
I've done next:
#IBDesignable
class RoundedImageView: UIImageView {
override init(image: UIImage?) {
super.init(image: image)
super.layer.cornerRadius = super.frame.size.height / 2
self.layer.cornerRadius = self.frame.size.height / 2
}
override init(frame: CGRect) {
super.init(frame: frame)
super.layer.cornerRadius = super.frame.size.height / 2
self.layer.cornerRadius = self.frame.size.height / 2
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
super.layer.cornerRadius = super.frame.size.height / 2
self.layer.cornerRadius = self.frame.size.height / 2
}
}
And my imageView in storyboard is RoundedImageView class selected.
But in storyboard it's still showing as rectangle. How can I realize it?
When I'm running code its rounded.
Thanks

You should set radius after layouts have been applied.
#IBDesignable
class RoundedImageView: UIImageView {
override init(image: UIImage?) {
super.init(image: image)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = self.frame.size.height / 2
self.clipsToBounds = true
}
}

Related

Custom view for NSMenuItem appearing blank

I've been trying to make a custom view for a NSMenuItem with an image on it. The code below overrides the original view, but without the image. The item appears blank and smaller.
This code is only an example!
class CustomItemView: NSView {
private let imageView: NSImageView = NSImageView()
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
// self.imageView.frame = frameRect
self.imageView.image = NSImage.init(named: "example")!
self.addSubview(self.imageView)
self.imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.imageView.centerXAnchor.constraint(equalTo: self.centerXAnchor),
self.imageView.centerYAnchor.constraint(equalTo: self.centerYAnchor),
self.imageView.widthAnchor.constraint(equalToConstant: 100),
self.imageView.heightAnchor.constraint(equalToConstant: 100)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I then simply add set the view like this
let newItem: NSMenuItem = NSMenuItem()
newItem.view = CustomItemView()
newItem.target = self
self.addItem(newItem)

Swift - get random CGPoints from UIView

I am trying to get random CGPoints along the 'outer contour' of UIView so that I will be able to draw UIBezierPath line over obtained CGPoints. For example, get CGPoints from below red dots which I marked myself by hand. Any idea?
###Edit###
As per Sweeper's advice I am trying to add CAShapeLayer into my custom view but it returns nil when I am printing its path. Please could you point out what I am missing?
class ViewController: UIViewController {
let shapeLayer = CAShapeLayer()
override func viewDidLoad() {
super.viewDidLoad()
let view = BubbleView(frame: CGRect(x: self.view.frame.midX / 2, y: self.view.frame.midY/2, width: 150, height: 100))
view.backgroundColor = .gray
view.layer.cornerRadius = 30
self.view.addSubview(view)
}
}
class BubbleView: UIView {
var pathLayer: CAShapeLayer!
override func layoutSubviews() {
pathLayer = CAShapeLayer()
pathLayer.bounds = frame
self.layer.addSublayer(pathLayer)
print(pathLayer.path) // returns nil
}
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .clear
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

UIView is not rounded

I have a small problem and not sure why it is not working. I have a code:
func rounded(cornerRadius: CGFloat? = nil) {
if let cornerRadius = cornerRadius {
layer.cornerRadius = cornerRadius
} else {
layer.cornerRadius = min(frame.size.height, frame.size.width) / 2
}
clipsToBounds = true
}
And I am trying to use like this:
cameraImageContainer.rounded()
cameraImageContainer = UIView
The image is not really very rounded and it doesn't look good.
Any Suggestions please?
Since the frame can change, it's easier to implement the corner radius when the bounds are set. Give this a try:
class CircleView: UIView {
override var bounds: CGRect {
didSet {
self.layer.cornerRadius = min(bounds.size.height, bounds.size.width) / 2
}
}
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.commonInit()
}
private func commonInit() {
clipsToBounds = true
}
}
Call the function to round the image in viewDidApper like this
override func viewDidAppear(_ animated: Bool) {
cameraImageContainer.rounded()
}
because the frames of the button will be set only after the view is loaded
if you waant to call it in viewDidLoad create a custom class for imageView and set it in the storybaord

Swift - UIView when done updating its frame?

I have a UITableViewCell in which I add my custom view, say
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
convenience required init(size: CGFloat) {
self.init(frame: CGRect.zero)
height = size
// init my other sub contents [1]
}
}
From my UITableViewCell:
let myView = MyView(size: 35)
contentView.addSubView(myView)
My problem: my other UI components in MyView depend on the width and height of MyView and it's too early to set their position in [1] because MyView's frame is now (x: 0, y: 0, width: 0, height: height)
Where should I put my other UI components in MyView? Is there a delegate in UIView that tells me: "Hey, the frame of the view is updated with its actual size."? (like viewDidAppear in a UIViewController)
Regards,
You can do
override var frame: NSRect {
didSet {
//update your subviews
}
}
In your MyView class. But really, you should just look into setting up proper constraints:
https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/

customize UIPageControl dots

I'm currently trying to customize the UIPageControl so it will fit my needs. However I seem to be having a problem when implementing some logic in the draw
What I want to do is to be able to user IBInspectable variables to draw out the UIPageControl however those seem to still be nil when the draw method is being called and when I try to implement my logic in the awakeFromNib for instance it won't work.
What I did so far is the following
class BoardingPager: UIPageControl {
#IBInspectable var size: CGSize!
#IBInspectable var borderColor: UIColor!
#IBInspectable var borderWidth: CGFloat! = 1
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.pageIndicatorTintColor = UIColor.clear
}
override func draw(_ rect: CGRect) {
super.draw(rect)
setDots()
}
func setDots() {
for i in (0..<self.numberOfPages) {
let dot = self.subviews[i]
if size != nil {
let dotFrame = CGRect(x: size.width/2, y: size.height/2, width: size.width, height: size.height)
dot.frame = dotFrame
}
if i != self.currentPage {
dot.layer.cornerRadius = dot.frame.size.height / 2
dot.layer.borderColor = borderColor.cgColor
dot.layer.borderWidth = borderWidth
}
}
}
}
Another problem I'm facing is that I want to remove/add a border when the current page changes.
I'm hoping someone will be able to help me out