am trying to add image views while looping in an array.. like this:
let v = [1,2,3]
w = self.playgroundimg.frame.width/3 - 48.89/2
h = self.playgroundimg.frame.height/4 - 17
for x in v {
let imageName3 = "lineupcardbg"
let image3 = UIImage(named: imageName3)
let imageView3 = UIImageView(image: image3!)
imageView3.frame = CGRect(x: w, y: h, width: 48.89, height: 70.15)
self.playgroundimg.addSubview(imageView3)
w = w + self.playgroundimg.frame.width/3 - 48.89 - 15
}
this is working fine, but the dimension of the imageview will be different from device to device .. like this:
iphonex:
iphone 7 plus:
as you can see the one in the middle is not centered to the one below it .. how to achieve this so the middle is in the center and the other two are beside it with some space? and be displayed the same in all sizes?
playgroundimg constraints:
Here is a simple example - just to show how to use constraints from code.
You can paste this into a new playground page and run it to see the results.
Change the line:
get { return CGSize(width: 400, height: 400) }
to different sizes to see that the views remain centered.
import PlaygroundSupport
import UIKit
class RoundedImageView: UIImageView {
override init(frame: CGRect) {
super.init(frame: frame)
layer.cornerRadius = 8
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class AlignViewController: UIViewController {
override public var preferredContentSize: CGSize {
get { return CGSize(width: 400, height: 400) }
set { super.preferredContentSize = newValue }
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .green
var theImageViews = [UIImageView]()
for _ in 0..<4 {
let imgView = RoundedImageView(frame: CGRect.zero)
imgView.translatesAutoresizingMaskIntoConstraints = false
imgView.backgroundColor = .white
view.addSubview(imgView)
// make all views the same size and width
NSLayoutConstraint.activate([
imgView.widthAnchor.constraint(equalToConstant: 48.89),
imgView.heightAnchor.constraint(equalToConstant: 70.15),
])
theImageViews.append(imgView)
}
// for easy identification of which views we're referencing
let leftView = theImageViews[0]
let centerView = theImageViews[1]
let rightView = theImageViews[2]
let bottomView = theImageViews[3]
NSLayoutConstraint.activate([
// "center view" will be centered horizontally, and a little above centered vertically
centerView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
centerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -25),
// left view is aligned to top of center view, and 20-pts to the left
leftView.topAnchor.constraint(equalTo: centerView.topAnchor),
leftView.trailingAnchor.constraint(equalTo: centerView.leadingAnchor, constant: -20),
// right view is aligned to top of center view, and 20-pts to the right
rightView.topAnchor.constraint(equalTo: centerView.topAnchor),
rightView.leadingAnchor.constraint(equalTo: centerView.trailingAnchor, constant: 20),
// bottom view is centerX aligned to center view, and 20-pts below
bottomView.topAnchor.constraint(equalTo: centerView.bottomAnchor, constant: 20),
bottomView.centerXAnchor.constraint(equalTo: centerView.centerXAnchor),
])
}
}
let viewController = AlignViewController()
PlaygroundPage.current.liveView = viewController
There are many ways to do things in autolayout. One way to solve this is to set the Leading and Trailing autolayout constraints for the playgroundimg view. That would make playgroundimg.frame.width adapt to the device screen width. And make sure that the constraints of the playgroundimg's superview are set.
In Xcode it would look like this for example:
You are using playgroundimg.frame.width in calculating the h and w variables, which I would suggest changing their names to x and y respectively since they denote coordinates and not a width or height:
x = self.playgroundimg.frame.width/3 - 48.89/2
y = self.playgroundimg.frame.height/4 - 17
And update this line too :
x = x + self.playgroundimg.frame.width/3 - 48.89 - 15
Related
Hello I am new at swift and IOS apps , I am trying to animate movement of cardBackImage (UIImage) from deckPileImage to the card view, but everything got different superViews and I have no idea how to do it properly , all the location have different frames ( superviews as described in the Image) , Should I use CGAffineTransform ?
viewHierarchyDescription
try to imagine my abstraction as a "face down card fly from deck into its possition on boardView"
Don't animate the view at all. Instead, animate a snapshot view as a proxy. You can see me doing it here, in this scene from one of my apps.
That red rectangle looks like it's magically flying out of one view hierarchy into another. But it isn't. In reality there are two red rectangles. I hide the first rectangle and show the snapshot view in its place, animate the snapshot view to where the other rectangle is lurking hidden, then hide the snapshot and show the other rectangle.
To help get you going...
First, no idea why you have your "deckPileImage" in a stack view, but assuming you have a reason for doing so...
a simple "card" view - bordered with rounded corners
class CardView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
layer.cornerRadius = 16
layer.masksToBounds = true
layer.borderWidth = 1
layer.borderColor = UIColor.black.cgColor
}
}
a basic view controller - adds a "deck pile view" to a stack view, and a "card position view" as the destination for the new, animated cards.
class AnimCardVC: UIViewController {
let deckStackView: UIStackView = UIStackView()
let cardPositionView: UIView = UIView()
let deckPileView: CardView = CardView()
let cardSize: CGSize = CGSize(width: 80, height: 120)
// card colors to cycle through
let colors: [UIColor] = [
.systemRed, .systemGreen, .systemBlue,
.systemCyan, .systemOrange,
]
var colorIDX: Int = 0
// card position constraints to animate
var animXAnchor: NSLayoutConstraint!
var animYAnchor: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
deckStackView.translatesAutoresizingMaskIntoConstraints = false
deckPileView.translatesAutoresizingMaskIntoConstraints = false
cardPositionView.translatesAutoresizingMaskIntoConstraints = false
deckStackView.addArrangedSubview(deckPileView)
view.addSubview(deckStackView)
view.addSubview(cardPositionView)
// always respect safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
deckStackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
deckStackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
// we'll let the stack view subviews determine its size
deckPileView.widthAnchor.constraint(equalToConstant: cardSize.width),
deckPileView.heightAnchor.constraint(equalToConstant: cardSize.height),
cardPositionView.topAnchor.constraint(equalTo: deckStackView.bottomAnchor, constant: 100.0),
cardPositionView.centerXAnchor.constraint(equalTo: g.centerXAnchor),
cardPositionView.widthAnchor.constraint(equalToConstant: cardSize.width + 2.0),
cardPositionView.heightAnchor.constraint(equalToConstant: cardSize.height + 2.0),
])
// outline the card holder view
cardPositionView.backgroundColor = .systemYellow
cardPositionView.layer.borderColor = UIColor.blue.cgColor
cardPositionView.layer.borderWidth = 2
// make the "deck card" gray to represent the deck
deckPileView.backgroundColor = .lightGray
}
func animCard() {
let card = CardView()
card.backgroundColor = colors[colorIDX % colors.count]
colorIDX += 1
card.translatesAutoresizingMaskIntoConstraints = false
card.widthAnchor.constraint(equalToConstant: cardSize.width).isActive = true
card.heightAnchor.constraint(equalToConstant: cardSize.height).isActive = true
view.addSubview(card)
// center the new card on the deckCard
animXAnchor = card.centerXAnchor.constraint(equalTo: deckPileView.centerXAnchor)
animYAnchor = card.centerYAnchor.constraint(equalTo: deckPileView.centerYAnchor)
// activate those constraints
animXAnchor.isActive = true
animYAnchor.isActive = true
// run the animation *after* the card has been placed at its starting position
DispatchQueue.main.async {
// de-activate the current constraints
self.animXAnchor.isActive = false
self.animYAnchor.isActive = false
// center the new card on the cardPositionView
self.animXAnchor = card.centerXAnchor.constraint(equalTo: self.cardPositionView.centerXAnchor)
self.animYAnchor = card.centerYAnchor.constraint(equalTo: self.cardPositionView.centerYAnchor)
// re-activate those constraints
self.animXAnchor.isActive = true
self.animYAnchor.isActive = true
// 1/2 second animation
UIView.animate(withDuration: 0.5, animations: {
self.view.layoutIfNeeded()
})
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
animCard()
}
}
It looks like this:
Each time you tap anywhere the code will add a new "card" and animate it from the "deck" view to the "card position" view.
I am using snap kit to set out constraints. The first image is what I'm trying to achieve with the code below. How can I set the constraints off the circle's width and height to be dynamic on any iPhone screen ?
profileImage = UIImageView()
profileImage.layer.borderWidth = 2
profileImage.layer.borderColor = UIColor.lightBlue.cgColor
profileImage.layer.cornerRadius = 130
profileImage.clipsToBounds = true
profileImage.layer.masksToBounds = true
let tapGesture = UITapGestureRecognizer(target: self, action:#selector((tappedImage)))
profileImage.addGestureRecognizer(tapGesture)
profileImage.isUserInteractionEnabled = true
profileImage.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(profileImage)
profileImage.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalTo(titleLabel.snp.bottom).offset(topMargin*2)
make.width.height.equalTo(view.snp.width).multipliedBy(0.71)
}
enter image description here
enter image description here
Couple points...
First, 71% of the view width will probably be too big. Start around 50% and adjust to your liking.
You are using .cornerRadius = 130 but your imageView may not be that size (certainly not on different devices), so you want to set the corner radius to one-half the width of the image view (or height, doesn't matter since it will be a square 1:1 ratio).
You could wait until viewDidLayoutSubviews() to find out the run-time size of the image view, but if your image view ends up as a subview of another view, it won't be set at that point either.
Much easier to create a very simple UIImageView subclass:
class ProfileImageView: UIImageView {
override func layoutSubviews() {
super.layoutSubviews()
layer.borderWidth = 2
layer.borderColor = UIColor.systemBlue.cgColor
layer.cornerRadius = bounds.width * 0.5
clipsToBounds = true
layer.masksToBounds = true
}
}
Then your view controller looks like this:
class ViewController: UIViewController {
var profileImage: ProfileImageView!
// your top margin value
let topMargin: CGFloat = 20
override func viewDidLoad() {
super.viewDidLoad()
profileImage = ProfileImageView()
if let img = UIImage(named: "sampleProfilePic") {
profileImage.image = img
}
profileImage.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(profileImage)
// respect safe-area
let g = view.safeAreaLayoutGuide
// this should give the same layout as your "snap" constraints
NSLayoutConstraint.activate([
// center horizontally
profileImage.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// your topMargin value * 2 from safe-area top
profileImage.topAnchor.constraint(equalTo: g.topAnchor, constant: topMargin * 2.0),
// width
// 71% of width of safe-area is probably too wide
// try starting at 50%
profileImage.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.50),
// 1:1 ratio (square)
profileImage.heightAnchor.constraint(equalTo: profileImage.widthAnchor),
])
// profileImage.snp.makeConstraints { (make) in
// make.centerX.equalToSuperview()
// make.top.equalTo(titleLabel.snp.bottom).offset(topMargin*2)
// make.width.height.equalTo(view.snp.width).multipliedBy(0.71)
// }
let tapGesture = UITapGestureRecognizer(target: self, action:#selector((tappedImage)))
profileImage.addGestureRecognizer(tapGesture)
profileImage.isUserInteractionEnabled = true
}
}
Whenever the size of your profileImage view changes, the ProfileImageView class' layoutSubviews() will automatically set the corner radius appropriately.
Im new to IOS development and I have two buttons in the UIView and when user select the option portrait or landscape, change the UIView re-size and change the background color as well and i need to add animation for that process.
As as ex:
User select portrait and then user can see red color UIVIew. after click the landscape option, animation should be started and it looks like, red color image come front and change the size (changing height and width) for landscape mode and go to previous position and change color to green. i have added small UIView animation on code and it is helpful to you identify the where should we start the animation and finish it. if someone know how to it properly, please, let me know and appreciate your help. please, refer below code
import UIKit
class ViewController: UIViewController {
let portraitWidth : CGFloat = 400
let portraitHeight : CGFloat = 500
let landscapeWidth : CGFloat = 700
let landscapeHeight : CGFloat = 400
var mainView: UIView!
var mainStackView: UIStackView!
let segment: UISegmentedControl = {
let segementControl = UISegmentedControl()
return segementControl
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.translatesAutoresizingMaskIntoConstraints = false
mainStackView = UIStackView()
mainStackView.axis = .vertical
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.alignment = .center
mainStackView.distribution = .equalCentering
self.view.addSubview(mainStackView)
self.segment.insertSegment(withTitle: "Portrait", at: 0, animated: false)
self.segment.insertSegment(withTitle: "Landscape", at: 1, animated: false)
self.segment.selectedSegmentIndex = 0
self.segment.addTarget(self, action: #selector(changeOrientation(_:)), for: .valueChanged)
self.segment.translatesAutoresizingMaskIntoConstraints = false
self.segment.selectedSegmentIndex = 0
mainStackView.addArrangedSubview(self.segment)
let safeAreaLayoutGuide = self.view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
self.mainStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 20),
self.mainStackView.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor, constant: 0),
])
NSLayoutConstraint.activate([
self.segment.heightAnchor.constraint(equalToConstant: 35),
self.segment.widthAnchor.constraint(equalToConstant: 300)
])
mainView = UIView(frame: .zero)
mainView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.addArrangedSubview(mainView)
mainView.backgroundColor = UIColor.red
NSLayoutConstraint.activate([
mainView.heightAnchor.constraint(equalToConstant: portraitHeight),
mainView.widthAnchor.constraint(equalToConstant: portraitWidth),
mainView.topAnchor.constraint(equalTo: segment.bottomAnchor, constant: 30)
])
}
#IBAction func changeOrientation(_ sender: UISegmentedControl) {
self.mainView.constraints.forEach{ (constraint) in
self.mainView.removeConstraint(constraint)
}
UIView.animate(withDuration: 1.0) {
if (sender.selectedSegmentIndex == 0) {
self.mainView.backgroundColor = UIColor.red
NSLayoutConstraint.activate([
self.mainView.heightAnchor.constraint(equalToConstant: self.portraitHeight),
self.mainView.widthAnchor.constraint(equalToConstant: self.portraitWidth),
self.mainView.topAnchor.constraint(equalTo: self.segment.bottomAnchor, constant: 30)
])
} else {
self.mainView.backgroundColor = UIColor.green
NSLayoutConstraint.activate([
self.mainView.heightAnchor.constraint(equalToConstant: self.landscapeHeight),
self.mainView.widthAnchor.constraint(equalToConstant: self.landscapeWidth),
self.mainView.topAnchor.constraint(equalTo: self.segment.bottomAnchor, constant: 30)
])
}
}
}
}
updated logic
#IBAction func changeOrientation(_ sender: UISegmentedControl) {
UIView.animate(withDuration: 4.0) {
if (sender.selectedSegmentIndex == 0) {
self.mainView.backgroundColor = UIColor.red
self.widthConstraint.constant = self.portraitWidth
self.heightConstraint.constant = self.portraitWidth
} else {
self.mainView.backgroundColor = UIColor.green
self.widthConstraint.constant = self.landscapeWidth
self.heightConstraint.constant = self.landscapeHeight
}
self.mainView.layoutIfNeeded()
} }
It's possible, the basic problem is:
• It's not possible to animate an actual change between one constraint and another.
To change size or shape you simply animate the length of a constraint.
While you are learning I would truly urge you to simply animate the constraints.
So, don't try to "change" constraints, simply animate the length of one or the other.
yourConstraint.constant = 99 // it's that easy
I also truly urge you to just lay it out on storyboard.
You must master that first!
Also there is no reason at all for the stack view, get rid of it for now.
Just have an outlet
#IBOutlet var yourConstraint: NSLayoutConstraint!
and animate
UIView.animateWithDuration(4.0) {
self.yourConstraint.constant = 666
self.view.layoutIfNeeded()
}
Be sure to search in Stack Overflow for "iOS animate constraints" as there is a great deal to learn.
Do this on storyboard, it will take 20 seconds tops for such a simple thing. Once you have mastered storyboard, only then move on to code if there is some reason to do so
Forget the stack view
Simply animate the constant of the constraint(s) to change the size, shape or anything you like.
Be sure to google for the many great articles "animating constraints in iOS" both here on SO and other sites!
I want to set an image as background that the content mode is scaleAspectFill and stretch the bottom pixel of line to fullscreen.
Here is a simple sample image that the size is 1280x300px that will be set in Assets as 2x.
Here is a screenshot of the storyboard. I want to fill the the bottom pixel of line to the white space.
I have tried the Stretching and the Slicing feature but both effect are not what I want.
Here is the expected result what I want on iPhone 4S.
It's not clear how you are sizing your image...
The 1280 x 300 image you posted, with the imageView constrained to the width of the view...
AspectFit:
AspectFill (using the image's original 300 height):
AspectFill (using 150 height):
However, assuming the text in your images will have varying lengths, you may wind up with...
AspectFit:
AspectFill (using 150 height):
However... assuming you have a plan for solving that, one approach would be to use two image views.
The top image view would hold your full image as you already have it... using .scaleAspectFill and constraining its height to show just the centered text in the image.
The bottom image view would be constrained to the bottom of the view, with .scaleToFill, and you could use this extension:
extension UIImage {
// return the CGRect portion as a new UIImage
func subImage(in rect: CGRect) -> UIImage? {
let scale = UIScreen.main.scale
guard let cgImage = cgImage else { return nil }
guard let crop = cgImage.cropping(to: rect) else { return nil }
return UIImage(cgImage: crop, scale: scale, orientation:.up)
}
}
// then, use it like this
let bottomImage = fullImage.subImage(in: CGRect(x: 0.0, y: fullImage.size.height - 1.0, width: 8.0, height: 1.0))
to get an 8px x 1px portion of the original image. Set the .image of the bottom image view to that image and it will scale to fill the entire frame.
Result:
and here is a complete example, using your original image (I named it "wake.png"):
extension UIImage {
// return the CGRect portion as a new UIImage
func subImage(in rect: CGRect) -> UIImage? {
let scale = UIScreen.main.scale
guard let cgImage = cgImage else { return nil }
guard let crop = cgImage.cropping(to: rect) else { return nil }
return UIImage(cgImage: crop, scale: scale, orientation:.up)
}
}
class StretchBottomViewController: UIViewController {
var topImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleAspectFill
v.setContentHuggingPriority(.required, for: .vertical)
return v
}()
var bottomImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleToFill
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(topImageView)
view.addSubview(bottomImageView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain top image view to top / leading / trailing at Zero
topImageView.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
topImageView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
topImageView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
// constrain bottom image view to bottom of top image view / leading / trailing at Zero
bottomImageView.topAnchor.constraint(equalTo: topImageView.bottomAnchor, constant: 0.0),
bottomImageView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
bottomImageView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
// constrain bottom image view to bottom at Zero
bottomImageView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
// however you are determining the height of the top image view
// using 150 here to work with your original image
topImageView.heightAnchor.constraint(equalToConstant: 150.0),
])
// load "wake me up" image
if let fullImage = UIImage(named: "wake") {
// get the bottom part of the full image (8 pixels wide, 1-pixel tall)
if let bottomImage = fullImage.subImage(in: CGRect(x: 0.0, y: fullImage.size.height - 1.0, width: 8.0, height: 1.0)) {
topImageView.image = fullImage
bottomImageView.image = bottomImage
}
}
}
}
Try to use (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode with resizingModel is .stretch
If you want the text is docked at the top, the blue vertical line is in the bottom, so let's try this (assuming that the blue line height is 20px, the distance from the top of image to bottom of text 'Before you go' is 100 px)
let image = yourOriginalImage.resizableImage(withCapInsets: UIEdgeInsets(top: 100, left: 10, bottom: 10, right: 10), resizingMode: .stretch)
Hope it helps.
Update
Below is what display with the above lines of code
I am trying to put an icon next to a button label.
Problem: Interface Builder puts the button-image not to the right side. So there is still some space next to the (x).
Thanks for your help
You can do this in Interface Builder by setting the title and image insets:
In this case I've set the title right inset to 30 and the image left inset to 80. You can achieve the same in code by setting the UIButton's imageEdgeInset and titleEdgeInset properties. Knowing the size of the UIButton's subviews, you could probably calculate the edge insets using something like this:
CGSize labelWidth = myButton.titleLabel.frame.size.width;
CGSize imageWidth = myButton.imageView.frame.size.width;
myButton.titleEdgeInsets = (UIEdgeInsets){0.0, -imageWidth, 0.0, imageWidth};
myButton.imageEdgeInsets = (UIEdgeInsets){0.0, labelWidth, 0.0, -labelWidth};
In Xcode 8 you will find those attributes in the Size inspector:
select image(if (x) is image) or title (if (x) is simply key) on the window and set left , Right offsets according to your need
i have achieved this:
class CustomButton: UIButton {
open var rightIcon: UIImage? {
didSet {
rightIconImage = UIImageView(image: rightIcon?.withRenderingMode(.alwaysTemplate))
rightIconImage?.tintColor = .white
if let rightIconImage = rightIconImage {
addSubview(rightIconImage)
}
layoutSubviews()
}
}
open override func layoutSubviews() {
super.layoutSubviews()
setupRightIconIfNeeded()
}
func setupRightIconIfNeeded() {
if let rightIconImage = rightIconImage {
rightIconImage.translatesAutoresizingMaskIntoConstraints = false
titleLabel?.translatesAutoresizingMaskIntoConstraints = false
if let titleLabel = titleLabel, titleLabel.frame.width > 0 {
let paddingLeft = (frame.width - titleLabel.frame.width - spacing - iconSize) / 2
NSLayoutConstraint.deactivate(constraints)
NSLayoutConstraint.deactivate(titleLabel.constraints)
NSLayoutConstraint.activate([
//set height constraint for button
heightAnchor.constraint(equalToConstant: apolloSize.height),
//set constraint for title label
titleLabel.widthAnchor.constraint(equalToConstant: titleLabel.frame.width),
titleLabel.heightAnchor.constraint(equalToConstant: titleLabel.frame.height),
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: paddingLeft),
//set constraint for right icon
rightIconImage.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: spacing),
rightIconImage.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor),
rightIconImage.widthAnchor.constraint(equalToConstant: iconSize),
rightIconImage.heightAnchor.constraint(equalToConstant: iconSize)
])
}
}
}
}