Constraints don't work properly - ios

I'm currently working on a project and I've created a custom view programmatically.
Here's the code I've written in the custom class:
class CodeView: UIView {
let codeTextView = UITextView()
let nameLabel = UILabel()
let dateLabel = UILabel()
let mainStackView = UIStackView()
let labelStackView = UIStackView()
let buttonStackView = UIStackView()
let lowerStackView = UIStackView()
let copyButton = UIButton()
let shareButton = UIButton()
let size = CGRect(x: 0, y: 0, width: 250, height: 175)
public init(name: String?, date: String?, code: String) {
if let name = name {
nameLabel.text = name
} else {
nameLabel.isHidden = true
}
if let date = date {
dateLabel.text = date
} else {
dateLabel.isHidden = true
}
codeTextView.text = code
super.init(frame: CGRect(x: 0, y: 0, width: 250, height: 175))
subview()
setup()
addingConstraints()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func setup() {
self.layer.cornerRadius = 15
self.backgroundColor = .white
codeTextView.textColor = .white
codeTextView.backgroundColor = UIColor(red: 2/255, green: 11/255, blue: 57/255, alpha: 0.75)
codeTextView.layer.cornerRadius = 15
codeTextView.font = UIFont(name: "Avenir-Medium", size: 15)
nameLabel.font = UIFont(name: "Avenir-Medium", size: 17)
dateLabel.font = UIFont(name: "Avenir-Light", size: 17)
copyButton.setImage(UIImage(named: "Copy"), for: .normal)
copyButton.setImage(UIImage(named: "Copy Highlighted"), for: .highlighted)
copyButton.setImage(UIImage(named: "Copy Highlighted"), for: .selected)
copyButton.addTarget(self, action: #selector(copyText), for: .touchUpInside)
copyButton.setTitle("", for: .normal)
copyButton.imageView?.contentMode = .scaleAspectFit
shareButton.setImage(UIImage(named: "Share"), for: .normal)
shareButton.setImage(UIImage(named: "Share Highlighted"), for: .highlighted)
shareButton.setImage(UIImage(named: "Share Highlighted"), for: .selected)
shareButton.addTarget(self, action: #selector(shareText), for: .touchUpInside)
shareButton.setTitle("", for: .normal)
shareButton.imageView?.contentMode = .scaleAspectFit
mainStackView.axis = .vertical
mainStackView.spacing = 10
lowerStackView.axis = .horizontal
lowerStackView.alignment = .center
lowerStackView.distribution = .fillProportionally
labelStackView.axis = .vertical
buttonStackView.axis = .horizontal
buttonStackView.alignment = .fill
buttonStackView.distribution = .fillEqually
buttonStackView.spacing = 10
}
func addingConstraints() {
//TranslatesAutoresizingMaskIntoConstraints = false
self.translatesAutoresizingMaskIntoConstraints = false
codeTextView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.translatesAutoresizingMaskIntoConstraints = false
labelStackView.translatesAutoresizingMaskIntoConstraints = false
buttonStackView.translatesAutoresizingMaskIntoConstraints = false
nameLabel.translatesAutoresizingMaskIntoConstraints = false
dateLabel.translatesAutoresizingMaskIntoConstraints = false
copyButton.translatesAutoresizingMaskIntoConstraints = false
shareButton.translatesAutoresizingMaskIntoConstraints = false
var constraint = [NSLayoutConstraint]()
let ViewWidth = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 250)
let ViewHeight = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 175)
let MainStackViewCenterX = NSLayoutConstraint(item: mainStackView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0)
let MainStackViewCenterY = NSLayoutConstraint(item: mainStackView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0)
let MainStackViewTop = NSLayoutConstraint(item: mainStackView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .topMargin, multiplier: 1, constant: 5)
let MainStackViewLeft = NSLayoutConstraint(item: mainStackView, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leadingMargin, multiplier: 1, constant: 5)
let MainStackViewRight = NSLayoutConstraint(item: mainStackView, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailingMargin, multiplier: 1, constant: 5)
let CodeTextViewTop = NSLayoutConstraint(item: codeTextView, attribute: .top, relatedBy: .equal, toItem: mainStackView, attribute: .topMargin, multiplier: 1, constant: 0)
let CodeTextViewLeft = NSLayoutConstraint(item: codeTextView, attribute: .leading, relatedBy: .equal, toItem: mainStackView, attribute: .leadingMargin, multiplier: 1, constant: 0)
let CodeTextViewRight = NSLayoutConstraint(item: codeTextView, attribute: .trailing, relatedBy: .equal, toItem: mainStackView, attribute: .trailingMargin, multiplier: 1, constant: 0)
let LowerStackViewBottom = NSLayoutConstraint(item: lowerStackView, attribute: .bottom, relatedBy: .equal, toItem: mainStackView, attribute: .bottomMargin, multiplier: 1, constant: 0)
let LowerStackViewLeft = NSLayoutConstraint(item: lowerStackView, attribute: .leading, relatedBy: .equal, toItem: mainStackView, attribute: .leadingMargin, multiplier: 1, constant: 0)
let LowerStackViewRight = NSLayoutConstraint(item: lowerStackView, attribute: .trailing, relatedBy: .equal, toItem: mainStackView, attribute: .trailingMargin, multiplier: 1, constant: 0)
let LabelStackViewCenterY = NSLayoutConstraint(item: labelStackView, attribute: .centerY, relatedBy: .equal, toItem: lowerStackView, attribute: .centerY, multiplier: 1, constant: 0)
let LabelStackViewLeft = NSLayoutConstraint(item: labelStackView, attribute: .leading, relatedBy: .equal, toItem: lowerStackView, attribute: .leadingMargin, multiplier: 1, constant: 0)
let ButtonStackViewCenterY = NSLayoutConstraint(item: buttonStackView, attribute: .centerY, relatedBy: .equal, toItem: lowerStackView, attribute: .centerY, multiplier: 1, constant: 0)
let ButtonStackViewRight = NSLayoutConstraint(item: buttonStackView, attribute: .trailing, relatedBy: .equal, toItem: lowerStackView, attribute: .trailingMargin, multiplier: 1, constant: 0)
let CopyButtonWidth = NSLayoutConstraint(item: copyButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: 28)
let CopyButtonHeight = NSLayoutConstraint(item: copyButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 35)
constraint.append(contentsOf: [ViewHeight, ViewWidth, MainStackViewCenterX, MainStackViewCenterY, MainStackViewTop, MainStackViewLeft, MainStackViewRight, CodeTextViewTop, CodeTextViewLeft, CodeTextViewRight, LowerStackViewBottom, LowerStackViewLeft, LowerStackViewRight, LabelStackViewCenterY, LabelStackViewLeft, ButtonStackViewCenterY, ButtonStackViewRight, CopyButtonWidth, CopyButtonHeight])
NSLayoutConstraint.activate(constraint)
}
func subview() {
self.addSubview(codeTextView)
self.addSubview(nameLabel)
self.addSubview(dateLabel)
self.addSubview(copyButton)
self.addSubview(shareButton)
self.addSubview(mainStackView)
self.addSubview(lowerStackView)
self.addSubview(labelStackView)
self.addSubview(buttonStackView)
mainStackView.addArrangedSubview(codeTextView)
mainStackView.addArrangedSubview(lowerStackView)
lowerStackView.addArrangedSubview(labelStackView)
lowerStackView.addArrangedSubview(buttonStackView)
labelStackView.addArrangedSubview(nameLabel)
labelStackView.addArrangedSubview(dateLabel)
buttonStackView.addArrangedSubview(copyButton)
buttonStackView.addArrangedSubview(shareButton)
}
func copyText() {
UIPasteboard.general.string = codeTextView.text
}
func shareText() {
let alert = UIAlertController(title: "Share?", message: "You probably don't want to share your code to everyone out there", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alert.addAction(UIAlertAction(title: "Share", style: .default, handler: { (action) in
let activity = UIActivityViewController(activityItems: [self.codeTextView.text], applicationActivities: nil)
UIApplication.shared.keyWindow?.rootViewController?.present(activity, animated: true, completion: nil)
}))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
}
}
And here's the code I wrote when I wanted to add the view to the app:
#IBOutlet weak var contentView: UIView!
let codeView1 = CodeView(name: "Hello", date: "Today", code: "Bla bla bla")
let stackView = UIStackView()
var viewArray = [CodeView]()
override func viewDidLoad() {
super.viewDidLoad()
viewArray.append(codeView1)
for i in viewArray {
stackView.addArrangedSubview(i)
}
contentView.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.alignment = .center
stackView.spacing = 20
let centerX = NSLayoutConstraint(item: stackView, attribute: .centerX, relatedBy: .equal, toItem: contentView, attribute: .centerX, multiplier: 1, constant: 0)
let centerY = NSLayoutConstraint(item: stackView, attribute: .centerY, relatedBy: .equal, toItem: contentView, attribute: .centerY, multiplier: 1, constant: 0)
NSLayoutConstraint.activate([centerX, centerY])
}
But after running the app it looks like this
Even though I want it to look like this
I've added the exact same constraints in the code as I used in the storyboard.
Thank you very much, I really appreciate every kind of help

When coding constraints programmatically it is often best to use iOS 9 constraint anchors. Here is a snippet of the constraint anchors code I used for a user's cell in a chat app I developed programmatically.
//ios 9 constraint anchors
//need x,y,width,height anchors
profileImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8).isActive = true
profileImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 48).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 48).isActive = true
//need x,y,width,height anchors
timeLabel.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
timeLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 18).isActive = true
timeLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
timeLabel.heightAnchor.constraint(equalTo: textLabel!.heightAnchor).isActive = true
}
Obviously, the details of your constraints will differ from this example, but this should give you a template to experiment with in order to resolve your issue.

Related

Swift: Custom Navigationbar with centered buttons

I have written a custom navigationbar but habe the problem, that the text inside my buttons is not perfectly aligned. For example see the + Button.
Any ideas how to improve this?
import UIKit
class DashboardNavbar: UINavigationBar {
var titleLabel: UILabel?
private var plusButton: UIButton?
private var editButton: UIButton?
var tap: UIGestureRecognizer?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
isTranslucent = false
addTitleLabel()
addPlusButton()
addEditButton()
}
private func addTitleLabel() {
titleLabel = UILabel()
titleLabel?.textColor = Styling.navigationbarTintColor
titleLabel?.translatesAutoresizingMaskIntoConstraints = false
titleLabel?.font = UIFont(name: "DIN Alternate", size: 17)
if let titleLabel = titleLabel{
addSubview(titleLabel)
let leadingConstraint = NSLayoutConstraint(item: titleLabel, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 15)
addConstraint(leadingConstraint)
let centerYConstraint = NSLayoutConstraint(item: titleLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0)
addConstraint(centerYConstraint)
}
}
private func addPlusButton(){
plusButton = UIButton(type: .custom)
plusButton?.setTitle("+", for: .normal)
plusButton?.layer.backgroundColor = Styling.navigationbarTintColor.cgColor
plusButton?.layer.cornerRadius = 15
plusButton?.setTitleColor(.black, for: .normal)
plusButton?.titleLabel?.font = UIFont(name: "DIN Alternate", size: 20)
plusButton?.contentVerticalAlignment = .center
plusButton?.contentHorizontalAlignment = .center
plusButton?.titleLabel?.baselineAdjustment = .alignCenters
if let plusButton = plusButton{
addSubview(plusButton)
plusButton.translatesAutoresizingMaskIntoConstraints = false
let trailingConstraint = NSLayoutConstraint(item: plusButton, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1.0, constant: -15)
addConstraint(trailingConstraint)
let centerYConstraint = NSLayoutConstraint(item: plusButton, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0)
addConstraint(centerYConstraint)
let widthC = NSLayoutConstraint(item: plusButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)
addConstraint(widthC)
let heightC = NSLayoutConstraint(item: plusButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)
addConstraint(heightC)
}
}
private func addEditButton(){
editButton = UIButton(type: .custom)
editButton?.setTitle(LocalizedString("EDIT"), for: .normal)
editButton?.layer.backgroundColor = Styling.navigationbarTintColor.cgColor
editButton?.layer.cornerRadius = 15
editButton?.setTitleColor(.black, for: .normal)
editButton?.titleLabel?.font = UIFont(name: "DIN Alternate", size: 16)
editButton?.contentVerticalAlignment = .center
editButton?.contentHorizontalAlignment = .center
editButton?.titleLabel?.baselineAdjustment = .alignCenters
if let editButton = editButton{
addSubview(editButton)
editButton.translatesAutoresizingMaskIntoConstraints = false
let trailingConstraint = NSLayoutConstraint(item: editButton, attribute: .trailing, relatedBy: .equal, toItem: plusButton!, attribute: .leading, multiplier: 1.0, constant: -15)
addConstraint(trailingConstraint)
let centerYConstraint = NSLayoutConstraint(item: editButton, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0)
addConstraint(centerYConstraint)
let widthC = NSLayoutConstraint(item: editButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 80)
addConstraint(widthC)
let heightC = NSLayoutConstraint(item: editButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 30)
addConstraint(heightC)
}
}
func setTitle(title: String){
titleLabel?.text = title
}
}
There several ways to correct this:
Use + image, image will be centered correctly on UIButton.
Change title insets of the UIButton, give some more inset from bottom and left, UIButton has titleInsets property;
Change the font o_O which is silly idea but also work, you can edit the font and make "+" sign to be centered on the drawing area.
Hope this helps! Good luck!

How to resolve : Unable to simultaneously satisfy constraints

I want to create like this ( Done through storyboard )
This Done through storyboard. In my observation I found the constrain problem arise from "totalAmountImg". I don't change the priority property of all objects (all have priority == 1000)
This is the result. (SummaryVC - Done this programatically)
NOTE : I want to make the SummaryVC totalAmountImg ( Programatically ) look like above image (Made by storyboard)
Stroryboard constraints for totalAmountImg
This exactly I create through code. But I don't know why this error pop out.
totalImgConstraint
func totalAmountImgConstraints() {
let imgCenterY = NSLayoutConstraint(item: totalAmountImg,
attribute: .centerY,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .centerY,
multiplier: 1.0,
constant: 0)
imgCenterY.identifier = "imgCenterY"
imgCenterY.isActive = true
let imgRight = NSLayoutConstraint(item: totalAmountImg,
attribute: .right,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .right,
multiplier: 1.0,
constant: 16)
imgRight.identifier = "imgRight"
imgRight.isActive = true
let imgAspectRatio = NSLayoutConstraint(item: totalAmountImg,
attribute: .height,
relatedBy: .equal,
toItem: totalAmountImg,
attribute: .width,
multiplier: 1.0 / 1.0,
constant: 0)
imgAspectRatio.identifier = "imgAspectRatio"
imgAspectRatio.isActive = true
let imgLeft = NSLayoutConstraint(item: totalAmountImg,
attribute: .left,
relatedBy: .equal,
toItem: totalPriceLbl,
attribute: .right,
multiplier: 1.0,
constant: 4)
imgLeft.identifier = "imgLeft"
imgLeft.isActive = true
let imgWidth = NSLayoutConstraint(item: totalAmountImg,
attribute: .width,
relatedBy: .lessThanOrEqual,
toItem: totalAmountView,
attribute: .width,
multiplier: 0.2,
constant: 0)
imgWidth.identifier = "imgWidth"
imgWidth.isActive = true
}
SummaryVC
class SummaryVC: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pageController: UIPageControl!
let numberOfPages = 3
override func viewDidLoad() {
super.viewDidLoad()
basicDesignSetup()
// Add subViews
scrollView.addSubview(summaryBaseView)
scrollView.addSubview(paymentTypeBaseView)
scrollView.addSubview(itemNameBaseView)
summaryBaseView.addSubview(totalAmountView)
summaryBaseView.addSubview(runningTableView)
summaryBaseView.addSubview(partnerAmountView)
totalAmountView.addSubview(totalLbl)
totalAmountView.addSubview(totalPriceLbl)
totalAmountView.addSubview(totalAmountImg)
view.setNeedsUpdateConstraints()
// set content size
scrollView.contentSize = CGSize(width: scrollView.frame.width * CGFloat(numberOfPages), height: scrollView.frame.height)
}
override func viewDidLayoutSubviews() {
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = scrollView.contentOffset.x / scrollView.frame.width
pageController.currentPage = Int(pageNumber)
pageController.currentPageIndicatorTintColor = UIColor.white
}
//-----------------------------------------------------------------
// MARK: - Methods
//-----------------------------------------------------------------
func basicDesignSetup() {
pageController.numberOfPages = numberOfPages
let scrollViewSize = scrollView.frame.size
let scrollViewWidth = scrollView.frame.width
// Summary View
let summeryOrigin = CGPoint(x: 0, y: 0)
summaryBaseView = UIView(frame: CGRect(origin: summeryOrigin, size: scrollViewSize))
summaryBaseView.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
// Payment Type View
let paymentTypeOrigin = CGPoint(x: scrollViewWidth, y: 0)
paymentTypeBaseView = UIView(frame: CGRect(origin: paymentTypeOrigin, size: scrollViewSize))
paymentTypeBaseView.backgroundColor = #colorLiteral(red: 0.01680417731, green: 0.1983509958, blue: 1, alpha: 1)
// Item Name View
let itemNameOrigin = CGPoint(x: scrollViewWidth * 2, y: 0)
itemNameBaseView = UIView(frame: CGRect(origin: itemNameOrigin, size: scrollViewSize))
itemNameBaseView.backgroundColor = #colorLiteral(red: 0, green: 0.9914394021, blue: 1, alpha: 1)
// Total Amount View
totalAmountView.backgroundColor = #colorLiteral(red: 0.5480614305, green: 0.8129847646, blue: 0.6160266995, alpha: 1)
runningTableView.backgroundColor = #colorLiteral(red: 0.4280827343, green: 0.7700845003, blue: 0.9571052194, alpha: 1)
partnerAmountView.backgroundColor = #colorLiteral(red: 0.9137254902, green: 0.4470588235, blue: 0.4549019608, alpha: 1)
totalLbl.text = "Total Amount"
totalLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
totalLbl.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
totalLbl.font = UIFont.systemFont(ofSize: 16, weight: .medium)
totalPriceLbl.text = "5532.00"
totalPriceLbl.textColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
totalPriceLbl.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
totalAmountImg.contentMode = .scaleAspectFit
totalAmountImg.image = #imageLiteral(resourceName: "tick")
totalAmountImg.backgroundColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
}
//-----------------------------------------------------------------
// MARK: - Views - programatically
//-----------------------------------------------------------------
// Base Views
lazy var summaryBaseView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var paymentTypeBaseView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var itemNameBaseView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
// $$$$$ Summary Sub Views $$$$$
// Total Amount
lazy var totalAmountView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var totalLbl: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var totalPriceLbl: UnderlinedLabel = {
let label = UnderlinedLabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var totalAmountImg: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
// Running Table
lazy var runningTableView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var runningLbl: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var runningPriceLbl: UnderlinedLabel = {
let label = UnderlinedLabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var runningTableImg: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
// Partner Amount
lazy var partnerAmountView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
lazy var partnerLbl: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var partnerPriceLbl: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
lazy var partnerAmountImg: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
//-----------------------------------------------------------------
// MARK: - Constraints
//-----------------------------------------------------------------
override func updateViewConstraints() {
totalAmountViewConstraints()
runningTableViewConstraints()
partnerAmountViewConstraints()
// Total Amount View
totalLblConstraint()
totalPriceLblConstraints()
totalAmountImgConstraints()
super.updateViewConstraints()
}
func totalAmountViewConstraints() {
NSLayoutConstraint(item: totalAmountView,
attribute: .left,
relatedBy: .equal,
toItem: summaryBaseView,
attribute: .left,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalAmountView,
attribute: .right,
relatedBy: .equal,
toItem: summaryBaseView,
attribute: .right,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalAmountView,
attribute: .top,
relatedBy: .equal,
toItem: summaryBaseView,
attribute: .top,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalAmountView,
attribute: .bottom,
relatedBy: .equal,
toItem: runningTableView,
attribute: .top,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalAmountView,
attribute: .height,
relatedBy: .equal,
toItem: runningTableView,
attribute: .height,
multiplier: 1.0,
constant: 0).isActive = true
}
func runningTableViewConstraints() {
NSLayoutConstraint(item: runningTableView,
attribute: .leading,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .leading,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: runningTableView,
attribute: .trailing,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .trailing,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: runningTableView,
attribute: .top,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .bottom,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: runningTableView,
attribute: .bottom,
relatedBy: .equal,
toItem: partnerAmountView,
attribute: .top,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: runningTableView,
attribute: .height,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .height,
multiplier: 1.0,
constant: 0).isActive = true
}
func partnerAmountViewConstraints() {
NSLayoutConstraint(item: partnerAmountView,
attribute: .leading,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .leading,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: partnerAmountView,
attribute: .trailing,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .trailing,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: partnerAmountView,
attribute: .top,
relatedBy: .equal,
toItem: runningTableView,
attribute: .bottom,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: partnerAmountView,
attribute: .bottom,
relatedBy: .equal,
toItem: summaryBaseView,
attribute: .bottom,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: partnerAmountView,
attribute: .height,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .height,
multiplier: 1.0,
constant: 0).isActive = true
}
// Total Ammount Section Subviews
func totalLblConstraint() {
NSLayoutConstraint(item: totalLbl,
attribute: .top,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .top,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalLbl,
attribute: .left,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .left,
multiplier: 1.0,
constant: 16).isActive = true
NSLayoutConstraint(item: totalLbl,
attribute: .bottom,
relatedBy: .equal,
toItem: totalPriceLbl,
attribute: .top,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalLbl,
attribute: .height,
relatedBy: .equal,
toItem: totalPriceLbl,
attribute: .height,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalLbl,
attribute: .width,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .width,
multiplier: 0.7,
constant: 0).isActive = true
}
func totalPriceLblConstraints() {
NSLayoutConstraint(item: totalPriceLbl,
attribute: .top,
relatedBy: .equal,
toItem: totalLbl,
attribute: .bottom,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalPriceLbl,
attribute: .leading,
relatedBy: .equal,
toItem: totalLbl,
attribute: .leading,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalPriceLbl,
attribute: .bottom,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .bottom,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalPriceLbl,
attribute: .height,
relatedBy: .equal,
toItem: totalLbl,
attribute: .height,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalPriceLbl,
attribute: .width,
relatedBy: .equal,
toItem: totalLbl,
attribute: .width,
multiplier: 1.0,
constant: 0).isActive = true
NSLayoutConstraint(item: totalPriceLbl,
attribute: .trailing,
relatedBy: .equal,
toItem: totalLbl,
attribute: .trailing,
multiplier: 1.0,
constant: 0).isActive = true
}
func totalAmountImgConstraints() {
let imgCenterY = NSLayoutConstraint(item: totalAmountImg,
attribute: .centerY,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .centerY,
multiplier: 1.0,
constant: 0)
imgCenterY.identifier = "imgCenterY"
imgCenterY.isActive = true
let imgRight = NSLayoutConstraint(item: totalAmountImg,
attribute: .right,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .right,
multiplier: 1.0,
constant: 16)
imgRight.identifier = "imgRight"
imgRight.isActive = true
let imgAspectRatio = NSLayoutConstraint(item: totalAmountImg,
attribute: .height,
relatedBy: .equal,
toItem: totalAmountImg,
attribute: .width,
multiplier: 1.0 / 1.0,
constant: 0)
imgAspectRatio.identifier = "imgAspectRatio"
imgAspectRatio.isActive = true
let imgLeft = NSLayoutConstraint(item: totalAmountImg,
attribute: .left,
relatedBy: .equal,
toItem: totalPriceLbl,
attribute: .right,
multiplier: 1.0,
constant: 4)
imgLeft.identifier = "imgLeft"
imgLeft.isActive = true
let imgWidth = NSLayoutConstraint(item: totalAmountImg,
attribute: .width,
relatedBy: .lessThanOrEqual,
toItem: totalAmountView,
attribute: .width,
multiplier: 0.2,
constant: 0)
imgWidth.identifier = "imgWidth"
imgWidth.isActive = true
}
//-----------------------------------------------------------------
// MARK: - Actions
//-----------------------------------------------------------------
#IBAction func pageChange(_ sender: UIPageControl) {
let x = CGFloat(sender.currentPage) * scrollView.frame.width
scrollView.contentOffset = CGPoint(x: x, y: 0)
pageController.currentPageIndicatorTintColor = UIColor.white
}
}
extension NSLayoutConstraint {
override open var description: String {
let id = identifier ?? ""
return "id: \(id), constant: \(constant)" //you may print whatever you want here
}
}
LOG
2018-01-12 16:27:27.934408+0530 Cafe Point[13577:258401] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"id: , constant: 343.0",
"id: , constant: 0.0",
"id: , constant: 0.0",
"id: , constant: 16.0",
"id: , constant: 0.0",
"id: , constant: 0.0",
"id: , constant: 0.0",
"id: imgLeft, constant: 4.0",
"id: imgRight, constant: 16.0",
"id: imgWidth, constant: 0.0"
)
Will attempt to recover by breaking constraint
id: imgLeft, constant: 4.0
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Try changing to this:
let imgRight = NSLayoutConstraint(item: totalAmountImg,
attribute: .right,
relatedBy: .equal,
toItem: totalAmountView,
attribute: .right,
multiplier: 1.0,
constant: -16)
imgRight.identifier = "imgRight"
imgRight.isActive = true
(note the 16 changes to -16)
You have to be careful when comparing constraints from the storyboard to ones created programatically because the order matters.
As the Warning states:
Will attempt to recover by breaking constraint id: imgLeft, constant:
4.0
You are giving Left and Right constraint to Image View. But also assigning Width. It confuses the Image View since Left and Right Constraints are enough to satisfy Width requirement for the Image View.
Hence you can use two combinations: left/width or right/width.
You can use other combinations too but for that, we have to dig into Priority of constraints.
To correctly understand layout keep in mind when you give a view leading/left and trailing/right constraints then you don't have to give it a width , as if you're pinning a robe to two sides , if you want to give it a width then give it a centerX constraint , Same also applied to top,bottom then don't have to give height and if you want to give height then add centerY constraint , off course you can give a view leading , trailing and width constraints at the same time but to make sure they fit together

Adding constraints to a custom UIButton doesn't work

Hi I have the following code:
class MyController {
override func viewDidLoad() {
self.addButtons()
super.viewDidLoad()
}
func addButtons() {
let cancelButton = UIButton(type: .custom)
let validateButton = UIButton(type: .custom)
cancelButton.setImage(UIImage(named: "cancel_icon"), for: .normal)
validateButton.setImage(UIImage(named: "validate_icon"), for: .normal)
cancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
validateButton.addTarget(self, action: #selector(validateAction), for: .touchUpInside)
cancelButton.translatesAutoresizingMaskIntoConstraints = false
validateButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(cancelButton)
self.view.addSubview(validateButton)
let leftCancel = NSLayoutConstraint(item: cancelButton, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 16)
let bottomCancel = NSLayoutConstraint(item: cancelButton, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: 20)
let widthCancel = NSLayoutConstraint(item: cancelButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
let heightCancel = NSLayoutConstraint(item: cancelButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
let rightValidate = NSLayoutConstraint(item: validateButton, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: 16)
let bottomValidate = NSLayoutConstraint(item: validateButton, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: 20)
let widthValidate = NSLayoutConstraint(item: validateButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
let heightValidate = NSLayoutConstraint(item: validateButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
NSLayoutConstraint.activate([leftCancel, bottomCancel, rightValidate, bottomValidate, widthCancel, heightCancel, widthValidate, heightValidate])
self.view.layoutIfNeeded()
}
func cancelAction() {
self.dismiss(animated: true, completion: nil)
}
func validateAction() {
self.dismiss(animated: true, completion: nil)
}
}
So basically I'm just adding two buttons with a width and height constraint, and I set the cancelButton to the bottom left and the validateButton to the bottom right.
My buttons don't appear. When I set the frame of the buttons this way, it works though:
cancelButton.frame = CGRect(x: 16, y: self.view.frame.height - 40, width: 20, height: 20)
validateButton.frame = CGRect(x: self.view.frame.width - 36, y: self.view.frame.height - 40, width: 20, height: 20)
Does someone know what's wrong with my constraints?
Thanks!
VisualFormat has its uses, but it also has its own quirks - such as flexible spacing between elements. Here's a solution without VisualFormat:
//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport
class MyController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.addButtons()
}
func addButtons() {
let cancelButton = UIButton(type: .custom)
let validateButton = UIButton(type: .custom)
cancelButton.setImage(UIImage(named: "cancel_icon"), for: .normal)
validateButton.setImage(UIImage(named: "validate_icon"), for: .normal)
cancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
validateButton.addTarget(self, action: #selector(validateAction), for: .touchUpInside)
cancelButton.translatesAutoresizingMaskIntoConstraints = false
validateButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(cancelButton)
self.view.addSubview(validateButton)
validateButton.backgroundColor = UIColor.red
cancelButton.backgroundColor = UIColor.blue
validateButton.setTitle("V", for: UIControlState())
cancelButton.setTitle("C", for: UIControlState())
let leftCancel = NSLayoutConstraint(item: cancelButton, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1, constant: 16)
let bottomCancel = NSLayoutConstraint(item: cancelButton, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: -20)
let widthCancel = NSLayoutConstraint(item: cancelButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
let heightCancel = NSLayoutConstraint(item: cancelButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
let rightValidate = NSLayoutConstraint(item: validateButton, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1, constant: -16)
let bottomValidate = NSLayoutConstraint(item: validateButton, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1, constant: -20)
let widthValidate = NSLayoutConstraint(item: validateButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
let heightValidate = NSLayoutConstraint(item: validateButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 20)
NSLayoutConstraint.activate([leftCancel, bottomCancel, rightValidate, bottomValidate, widthCancel, heightCancel, widthValidate, heightValidate])
self.view.layoutIfNeeded()
}
func cancelAction() {
// self.dismiss(animated: true, completion: nil)
print("cancel")
}
func validateAction() {
// self.dismiss(animated: true, completion: nil)
print("validate")
}
}
var vc = MyController()
vc.view.backgroundColor = UIColor.green
vc.view.frame = CGRect(x: 0, y: 0, width: 400, height: 400)
PlaygroundPage.current.liveView = vc.view
PlaygroundPage.current.needsIndefiniteExecution = true
You should be able to copy/paste this into a Playground page to see the results. Note that I don't have your button images, so I "V" and "C" titles.
The key difference is setting the Bottom and Trailing values to negative - that is, you want the Bottom of the Button to be (Bottom of containing view MINUS 20). Likewise with the Trailing edge of the Button to be -16 from the trailing edge of the containing view.
It seems you are over complicating this.
You can achieve this easily with VisualFormat strings.
Have a look here https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage.html#//apple_ref/doc/uid/TP40010853-CH27-SW1
Here's an example using your code:
func addButtons() {
let cancelButton = UIButton(type: .custom)
let validateButton = UIButton(type: .custom)
cancelButton.setImage(UIImage(named: "cancel_icon"), for: .normal)
validateButton.setImage(UIImage(named: "validate_icon"), for: .normal)
cancelButton.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
validateButton.addTarget(self, action: #selector(validateAction), for: .touchUpInside)
cancelButton.translatesAutoresizingMaskIntoConstraints = false
validateButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(cancelButton)
self.view.addSubview(validateButton)
// With visual format strings
let views = ["cancelButton" : cancelButton, "validateButton" : validateButton]
let horizontalFormat = "|[cancelButton]-[validateButton(==cancelButton)]|"
let verticalFormat = "V:[cancelButton]-10-|"
let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: horizontalFormat, options:.alignAllBottom , metrics: nil, views: views)
let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: verticalFormat, options:.alignAllBottom, metrics: nil, views: views)
NSLayoutConstraint.activate(horizontalConstraints)
NSLayoutConstraint.activate(verticalConstraints)
self.view.layoutIfNeeded()
}

UIVisualEffectView not working

I'm trying to add a blur effect to my view using the following code :
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light)) as UIVisualEffectView
visualEffectView.frame = containerView.bounds
containerView.addSubview(visualEffectView)
containerView.userInteractionEnabled = true
containerView.bringSubviewToFront(visualEffectView)
visualEffectView.alpha = 1.0
However, I do not see any changes.
UPDATE
My apologies, but I don't think I made my intentions clear in the original question. What I want to achieve is something like this :
My view holds a UIImageView which fills the whole screen. Next, on the bottom of the screen, I have a container which is a UIView which holds some buttons etc. What I want to do is add a blur effect to the containerView, so that the UIImageView behind it is blurred, where the containerView is. So basically I set my containerView's alpha to 0.5, which means its semi transparent and I can see the image behind it. What I want to do now is for that image behind the containerView to be blurred.
CURRENT EFF :
CODE :
extension UIButton{
func setImage(image: UIImage?, inFrame frame: CGRect?, forState state: UIControlState){
self.setImage(image, forState: state)
if let frame = frame{
self.imageEdgeInsets = UIEdgeInsets(
top: frame.minY - self.frame.minY,
left: frame.minX - self.frame.minX,
bottom: self.frame.maxY - frame.maxY,
right: self.frame.maxX - frame.maxX
)
}
}
}
class SingleImageFeedView: UIViewController {
lazy var mainImageView : UIImageView = {
let imageView = UIImageView()
imageView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.width * 1.3)
imageView.contentMode = UIViewContentMode.ScaleAspectFill
imageView.backgroundColor = UIColor.clearColor()
imageView.image = UIImage(named: "pizza")
return imageView
}()
let containerView : UIView = {
let this = UIView(frame: CGRectMake(0,0, 600,150))
this.backgroundColor = UIColor.clearColor()
this.layer.cornerRadius = 5
this.layer.borderColor = UIColor(red: (69/255.0), green: (209/255.0), blue: (153/255.0), alpha: 1.0).CGColor
this.layer.borderWidth = 0.5
return this
}()
let captionAndProfileImageContainerView : UIView = {
let this = UIView()
//this.backgroundColor = UIColor(red: (69/255.0), green: (209/255.0), blue: (153/255.0), alpha: 0.0)
this.backgroundColor = UIColor.clearColor()
return this
}()
let profilePicImageView : UIImageView = {
let imageView = UIImageView()
imageView.frame = CGRectMake(0, 0, 53, 53)
imageView.backgroundColor = UIColor.clearColor()
imageView.image = UIImage(named: "pizza")
imageView.contentMode = UIViewContentMode.ScaleToFill
return imageView
}()
let captionTextView: UITextView = {
let textField = UITextView(frame: CGRectMake(0,0, 150, 100))
textField.textColor = UIColor.whiteColor()
textField.editable = false
textField.text = "dwwdwwwwdwddwd"
textField.backgroundColor = UIColor.clearColor()
textField.font = UIFont.systemFontOfSize(12.0)
return textField
}()
let dividerLineView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
return view
}()
let commentAndLikesContainerView : UIView = {
let view = UIView()
//view.backgroundColor = UIColor(red: (69/255.0), green: (209/255.0), blue: (153/255.0), alpha: 0.0)
view.backgroundColor = UIColor.clearColor()
return view
}()
let commentLabel : UILabel = {
let label = UILabel()
label.text = "23"
return label
}()
let likesLabel : UILabel = {
let label = UILabel()
label.text = "25"
return label
}()
let voteUpButton : UIButton = {
let button = UIButton(frame: CGRectMake(0,0,25,25))
button.setImage((scaleImage((UIImage(named: "upvote"))!, toSize: CGSizeMake(25, 25))), inFrame: CGRectMake(0,0,25,25), forState: .Normal)
button.imageView?.contentMode = UIViewContentMode.Center
button.imageView?.clipsToBounds = true
button.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)
return button
}()
let voteDownButton : UIButton = {
let button = UIButton(frame: CGRectMake(0,0,25,25))
button.setImage((scaleImage((UIImage(named: "upvote"))!, toSize: CGSizeMake(25, 25))), inFrame: CGRectMake(0,0,25,25), forState: .Normal)
button.imageView?.transform = CGAffineTransformMakeRotation((180.0 * CGFloat(M_PI)) / 180.0)
button.imageView?.contentMode = UIViewContentMode.Center
button.imageEdgeInsets = UIEdgeInsetsMake(6, 10, 10, 10)
button.imageView?.clipsToBounds = true
return button
}()
let commentButton : UIButton = {
let button = UIButton(frame: CGRectMake(0,0,25,25))
button.setImage((scaleImage((UIImage(named: "comment_feed_icon"))!, toSize: CGSizeMake(25, 25))), inFrame: CGRectMake(0,0,25,25), forState: .Normal)
button.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
button.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)
button.imageView?.clipsToBounds = true
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clearColor()
setupViews()
}
func setupViews() {
self.captionAndProfileImageContainerView.addSubview(profilePicImageView)
self.captionAndProfileImageContainerView.addSubview(captionTextView)
self.commentAndLikesContainerView.addSubview(voteUpButton)
self.commentAndLikesContainerView.addSubview(voteDownButton)
self.commentAndLikesContainerView.addSubview(commentButton)
self.commentAndLikesContainerView.addSubview(commentLabel)
self.commentAndLikesContainerView.addSubview(likesLabel)
self.containerView.addSubview(captionAndProfileImageContainerView)
self.containerView.addSubview(dividerLineView)
self.containerView.addSubview(commentAndLikesContainerView)
self.view.addSubview(containerView)
self.view.bringSubviewToFront(containerView)
self.view.addSubview(mainImageView)
self.containerView.bringSubviewToFront(captionAndProfileImageContainerView)
self.containerView.bringSubviewToFront(dividerLineView)
self.containerView.bringSubviewToFront(commentAndLikesContainerView)
profilePicImageView.translatesAutoresizingMaskIntoConstraints = false
captionTextView.translatesAutoresizingMaskIntoConstraints = false
voteDownButton.translatesAutoresizingMaskIntoConstraints = false
containerView.translatesAutoresizingMaskIntoConstraints = false
voteUpButton.translatesAutoresizingMaskIntoConstraints = false
commentLabel.translatesAutoresizingMaskIntoConstraints = false
commentButton.translatesAutoresizingMaskIntoConstraints = false
commentAndLikesContainerView.translatesAutoresizingMaskIntoConstraints = false
captionAndProfileImageContainerView.translatesAutoresizingMaskIntoConstraints = false
likesLabel.translatesAutoresizingMaskIntoConstraints = false
dividerLineView.translatesAutoresizingMaskIntoConstraints = false
mainImageView.translatesAutoresizingMaskIntoConstraints = false
//main imageview constraints
self.view.addConstraint(NSLayoutConstraint(item: mainImageView, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Top, multiplier: 1, constant: 35))
self.view.addConstraint(NSLayoutConstraint(item: mainImageView, attribute: .Leading, relatedBy: .Equal, toItem: self.view, attribute: .Leading, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: mainImageView, attribute: .Trailing, relatedBy: .Equal, toItem: self.view, attribute: .Trailing, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: mainImageView, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: mainImageView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: 0))
self.view.sendSubviewToBack(mainImageView)
//containerview constraints
self.view.addConstraint(NSLayoutConstraint(item: containerView, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: -10))
self.view.addConstraint(NSLayoutConstraint(item: containerView, attribute: .Leading, relatedBy: .Equal, toItem: self.view, attribute: .Leading, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: containerView, attribute: .Trailing, relatedBy: .Equal, toItem: self.view, attribute: .Trailing, multiplier: 1, constant: -10))
self.view.addConstraint(NSLayoutConstraint(item: containerView, attribute: .Top, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: -160))
//caption and profilepic constraints
self.view.addConstraint(NSLayoutConstraint(item: captionAndProfileImageContainerView, attribute: .Top, relatedBy: .Equal, toItem: containerView, attribute: .Top, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: captionAndProfileImageContainerView, attribute: .Leading, relatedBy: .Equal, toItem: containerView, attribute: .Leading, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: captionAndProfileImageContainerView, attribute: .Trailing, relatedBy: .Equal, toItem: containerView, attribute: .Trailing, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: captionAndProfileImageContainerView, attribute: .Bottom, relatedBy: .Equal, toItem: containerView, attribute: .Bottom, multiplier: 1, constant: -50))
self.view.addConstraintsWithFormat("H:|-8-[v0(50)]", views: profilePicImageView)
self.view.addConstraintsWithFormat("V:|-35-[v0(50)]", views: profilePicImageView)
profilePicImageView.layer.cornerRadius = 25
profilePicImageView.layer.masksToBounds = true
self.view.addConstraint(NSLayoutConstraint(item: captionTextView, attribute: .Top, relatedBy: .Equal, toItem: captionAndProfileImageContainerView, attribute: .Top, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: captionTextView, attribute: .Leading, relatedBy: .Equal, toItem: profilePicImageView, attribute: .Trailing, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: captionTextView, attribute: .Trailing, relatedBy: .Equal, toItem: captionAndProfileImageContainerView, attribute: .Trailing, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: captionTextView, attribute: .Bottom, relatedBy: .Equal, toItem: captionAndProfileImageContainerView, attribute: .Bottom, multiplier: 1, constant: 0))
//likes and comments and divider
self.view.addConstraint(NSLayoutConstraint(item: commentAndLikesContainerView, attribute: .Top, relatedBy: .Equal, toItem: captionAndProfileImageContainerView, attribute: .Bottom, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: commentAndLikesContainerView, attribute: .Leading, relatedBy: .Equal, toItem: containerView, attribute: .Leading, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: commentAndLikesContainerView, attribute: .Trailing, relatedBy: .Equal, toItem: containerView, attribute: .Trailing, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: commentAndLikesContainerView, attribute: .Bottom, relatedBy: .Equal, toItem: containerView, attribute: .Bottom, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: voteUpButton, attribute: .Top, relatedBy: .Equal, toItem: commentAndLikesContainerView, attribute: .Top, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: voteUpButton, attribute: .Leading, relatedBy: .Equal, toItem: commentAndLikesContainerView, attribute: .Leading, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: likesLabel, attribute: .Top, relatedBy: .Equal, toItem: commentAndLikesContainerView, attribute: .Top, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: likesLabel, attribute: .Leading, relatedBy: .Equal, toItem: voteUpButton, attribute: .Trailing, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: voteDownButton, attribute: .Top, relatedBy: .Equal, toItem: commentAndLikesContainerView, attribute: .Top, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: voteDownButton, attribute: .Leading, relatedBy: .Equal, toItem: likesLabel, attribute: .Trailing, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: commentButton, attribute: .Top, relatedBy: .Equal, toItem: commentAndLikesContainerView, attribute: .Top, multiplier: 1, constant: 0))
self.view.addConstraint(NSLayoutConstraint(item: commentButton, attribute: .Leading, relatedBy: .Equal, toItem: voteDownButton, attribute: .Trailing, multiplier: 1, constant: 30))
self.view.addConstraint(NSLayoutConstraint(item: commentLabel, attribute: .Top, relatedBy: .Equal, toItem: commentAndLikesContainerView, attribute: .Top, multiplier: 1, constant: 10))
self.view.addConstraint(NSLayoutConstraint(item: commentLabel, attribute: .Leading, relatedBy: .Equal, toItem: commentButton, attribute: .Trailing, multiplier: 1, constant: 10))
if !UIAccessibilityIsReduceTransparencyEnabled() {
self.containerView.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = containerView.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.containerView.insertSubview(blurEffectView, atIndex: 1) //if you have more UIViews, use an insertSubview API to place it where needed
}
else {
self.view.backgroundColor = UIColor(red: (69/255.0), green: (209/255.0), blue: (153/255.0), alpha: 0.5)
}
containerView.clipsToBounds = true
}
}
I made a simple project with a UIImageView and and a container. Applying the blur to the container blurred the underneath photo. The containers background is set to transparent in storyboard.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let containerView : UIView = {
let this = UIView(frame: CGRectMake(100,200, 200,200))
this.backgroundColor = UIColor.clearColor()
this.layer.cornerRadius = 5
this.layer.borderColor = UIColor(red: (69/255.0), green: (209/255.0), blue: (153/255.0), alpha: 1.0).CGColor
this.layer.borderWidth = 0.5
return this
}()
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
visualEffectView.frame = containerView.bounds
self.view.addSubview(containerView)
containerView.insertSubview(visualEffectView, atIndex: 0)
let secondImg = UIImageView(image: UIImage(named: "swift_tut.png"))
secondImg.frame = CGRectMake(150,250, 200,200)
self.view.addSubview(secondImg)
self.view.bringSubviewToFront(containerView)
// Do any additional setup after loading the view, typically from a nib.
}
Try This Code , working for me
if !UIAccessibilityIsReduceTransparencyEnabled() {
self.view.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.view.insertSubview(blurEffectView, atIndex: 1) //if you have more UIViews, use an insertSubview API to place it where needed
}
else {
self.view.backgroundColor = UIColor.blackColor()
}

How to use a custom UIView multiple times in a controller with different content?

I have created my own custom UIView for a popover that I have to display on a screen. My UIView looks like this:
class HelpTipsPopover: UIView {
weak var title: UILabel!
weak var myText: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
let strongTitle = UILabel()
title = strongTitle
let strongMyText = UILabel()
myText = strongMyText
self.addSubview(strongTitle)
title.translatesAutoresizingMaskIntoConstraints = false
if selected == true{
title.text = "Search"
title.font = UIFont(name: "HelveticaNeue-Bold", size: 12)
title.textColor = UIColor.TRLMBlueBlackColor()
let leftConstraint = NSLayoutConstraint(item: title, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1.0, constant: 10)
let topConstraint = NSLayoutConstraint(item: title, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1.0, constant: 10)
self.addConstraints([leftConstraint, topConstraint])
self.addSubview(strongMyText)
myText.translatesAutoresizingMaskIntoConstraints = false
myText.text = "Search equities to view the order book and market prints for specific moments in time."
myText.numberOfLines = 0
myText.lineBreakMode = NSLineBreakMode.ByWordWrapping
myText.font = UIFont(name: "Helvetica Neue", size: 12)
myText.textColor = UIColor.TRLMBlueBlackColor()
let leftDescription = NSLayoutConstraint(item: myText, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1.0, constant: 10)
let rightDescription = NSLayoutConstraint(item: myText, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1.0, constant: 10)
let topDescription = NSLayoutConstraint(item: myText, attribute: .Top, relatedBy: .Equal, toItem: title, attribute: .Bottom, multiplier: 1.0, constant: 5)
self.addConstraints([leftDescription, topDescription, rightDescription])
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
}
Now I have three popovers that I have to display in my view controller with different title and text in each popover. Here are the methods in my View Controller which displays those popovers:
func showPopover(){
self.view.addSubview(helpTipsPopover)
helpTipsPopover.tag = 1
helpTipsPopover.translatesAutoresizingMaskIntoConstraints = false
helpTipsPopover.layer.cornerRadius = 6
helpTipsPopover.backgroundColor = UIColor(white: 1.0, alpha: 0.8)
let leftConstraint = NSLayoutConstraint(item: helpTipsPopover, attribute: .Leading, relatedBy: .Equal, toItem: self.view, attribute: .Leading, multiplier: 1.0, constant: 10)
let topConstraint = NSLayoutConstraint(item: helpTipsPopover, attribute: .Top, relatedBy: .Equal, toItem: self.hotSpotOne, attribute: .Bottom, multiplier: 1.0, constant: 4)
let widthConstraint = NSLayoutConstraint(item: helpTipsPopover, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 200)
let heightConstraint = NSLayoutConstraint(item: self.helpTipsPopover, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 80)
self.view.addConstraints([leftConstraint, topConstraint, widthConstraint, heightConstraint])
}
func showPopoverTwo(){
self.view.addSubview(helpTipsPopover)
helpTipsPopover.tag = 1
helpTipsPopover.translatesAutoresizingMaskIntoConstraints = false
helpTipsPopover.layer.cornerRadius = 6
helpTipsPopover.backgroundColor = UIColor(white: 1.0, alpha: 0.8)
let centerConstraint = NSLayoutConstraint(item: helpTipsPopover, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1.0, constant: 0)
let topConstraint = NSLayoutConstraint(item: helpTipsPopover, attribute: .Top, relatedBy: .Equal, toItem: self.hotSpotTwo, attribute: .Bottom, multiplier: 1.0, constant: 4)
let widthConstraint = NSLayoutConstraint(item: helpTipsPopover, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 200)
let heightConstraint = NSLayoutConstraint(item: self.helpTipsPopover, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 80)
self.view.addConstraints([centerConstraint, topConstraint, widthConstraint, heightConstraint])
}
Now I want to achieve something like this:
So each popover should have different title and text but i want to reuse the same UIView. Any help is appreciated. Thanks!
Modify your init method
init(frame: CGRect, titleString: String, bodyString: String) {
super.init(frame: frame)
// Your current initializer
title.text = titleString
myText.text = bodyString
}
Then you can initialize a popup like this:
let frame = CGRectMake(0,0,180,100)
let titleString = "My Custom Title"
let bodyString = "This is a body. I'm explaining things to you here."
helpTipsPopoverOne = HelpTipsPopover(frame: frame, titleString: titleString, bodyString: bodyString)
Modify your display method to take a popup as a parameter. Then you can create popups and display with whatever text you'd like!

Resources