I'm trying to set left border to each table view cell programmatically. I'm using UIView as a border but I cannot display the UIView for some reason. Also how should I set the UIView height? Thank you.
class Cell: UITableViewCell {
var borderLeft: UIView = {
let view = UIView()
view.frame.size.width = 3
view.frame.size.height = 20
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.backgroundColor = .black
addSubview(borderLeft)
borderLeft.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
borderLeft.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
borderLeft.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I think there is a mistake on this anchor:
borderLeft.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0).isActive = true
try instead to swap with bottomAnchor, like:
borderLeft.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
also add constraints for width and height (please remove frame resizing since is being ignored by view.translatesAutoresizingMaskIntoConstraints = false)
borderLeft.heightAnchor.constraint(equalToConstant: 20).isActive = true
borderLeft.widthAnchor.constraint(equalToConstant: 3).isActive = true
borderLeft.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
borderLeft.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0).isActive = true
here the result:
Related
I am pretty new in Programming Swift so I am trying to achieve a scrollable task includes 20 labels inside. I made it with storyboard but programmatically I failed..
Thanks in advance, a green view background and 20 labels orange. Can anyone show me how ?
So i am not very fond of advertising, but raywenderlich has an awesome tutorial on how to do this. It is quite easy, but it comes down to a scrollable view and a tableview with navigation links.
https://www.raywenderlich.com/5662524-your-second-ios-and-swiftui-app
Again, i am not advertising, just sharing some videos that really helped me understand Swift!
And for answering your question:
Use
Scrollview { put here your to-do code
} end of body
There is your scrollable view with all the labels!
Below code will print your label 20 times with scrollview.
import UIKit
class ViewController: UIViewController {
let scrollView = UIScrollView()
var a = 0
var COnstant: CGFloat = 20
override func viewDidLoad() {
super.viewDidLoad()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.backgroundColor = .green
self.view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
while a<20 {
let label = UILabel()
label.backgroundColor = .orange
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = .black
label.text = "I'm label \(a)"
label.textAlignment = .center
scrollView.addSubview(label)
label.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 0).isActive = true
label.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 0).isActive = true
label.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: 0).isActive = true
label.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: COnstant).isActive = true
COnstant += 40
a = a+1
if a >= 20 { // if bottomanchor is not set then our scroll view doesnot work
label.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
}
}
}
}
I am creating a custom button and the code for this is below. All the styling elements are working, however my the name and image subviews are not being added. I am sure this is a simple error, but I would appreciate it if someone could help me. Thank you.
class MaterialButton: UIButton {
let name = UILabel()
let image = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
setupButton()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
setupButton()
}
func setupButton() {
name.textColor = .white
// name.font = UIFont(name: "HelveticaNeue-UltraLight",size: 10.0)
name.textAlignment = .center
self.layer.cornerRadius = 20
addSubview(name)
positionName()
addSubview(image)
positionImage()
}
func positionName() {
name.translatesAutoresizingMaskIntoConstraints = false
name.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 10).isActive = true
name.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
name.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
name.heightAnchor.constraint(equalToConstant: self.bounds.height - image.bounds.height - 20).isActive = true
}
func positionImage() {
image.translatesAutoresizingMaskIntoConstraints = false
image.heightAnchor.constraint(equalToConstant: image.bounds.width).isActive = true
image.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
image.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
image.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
}
}
Example of how button is implemented (other button was declared initialized with Material Button earlier in the code)
func setupOtherButton() { // Setting up plastic button
otherButton.name.text = "Other"
otherButton.name.textColor = .white
otherButton.backgroundColor = .gray
miniSV1.addSubview(otherButton) // Add plastic button to view
otherButton.addTarget(self, action: #selector(otherButtonTapped), for: .touchUpInside)
}
Well don't know the exact UI that you are implementing but I did some changes in your code and got the following UI:
So for the button in viewDidLoad :
class ViewController: UIViewController {
var otherButton = MaterialButton()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
otherButton.frame = CGRect(x: 10, y: 180, width: 140, height: 140)
otherButton.name.text = "Other"
otherButton.name.textColor = .white
otherButton.backgroundColor = .gray
self.view.addSubview(otherButton)
}
}
And few changes in the constraints:
class MaterialButton: UIButton {
let name = UILabel()
let image = UIImageView()
override init(frame: CGRect) {
super.init(frame: frame)
setupButton()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
setupButton()
}
func setupButton() {
image.backgroundColor = UIColor.yellow
addSubview(image)
positionImage()
name.textColor = .white
name.textAlignment = .center
name.backgroundColor = .blue
self.layer.cornerRadius = 20
addSubview(name)
positionName()
}
func positionName() {
name.translatesAutoresizingMaskIntoConstraints = false
name.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10).isActive = true
name.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
name.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
name.heightAnchor.constraint(equalToConstant: 20).isActive = true
}
func positionImage() {
image.translatesAutoresizingMaskIntoConstraints = false
image.heightAnchor.constraint(equalToConstant: 50).isActive = true
image.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -10).isActive = true
image.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
image.topAnchor.constraint(equalTo: self.topAnchor, constant: 10).isActive = true
}
}
Check out this URL for better understanding of the constraints programmatically:
How to add constraints programmatically using Swift
I need to set gradient color with to colors into UITextView with white background color like in instagram stories. Example below:
Ignore the constraints set in the following code, but the concept should go like this:
containerView = GradientView.init()
self.view.addSubview(containerView)
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
containerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
containerView.widthAnchor.constraint(equalToConstant: 220).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 50).isActive = true
containerView.backgroundColor = .white
textView = UITextView()
containerView.addSubview(textView)
textView.translatesAutoresizingMaskIntoConstraints = false
textView.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 0).isActive = true
textView.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: 0).isActive = true
textView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 0).isActive = true
textView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: 0).isActive = true
textView.text = "#SomeValue"
textView.font = UIFont.systemFont(ofSize: 22, weight: .bold)
containerView.layer.mask = textView.layer.sublayers?.last
where GradientView is a UIView subclass similar to :
class GradientView: UIView{
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func addGradient(){
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.colors = [UIColor.blue.cgColor,UIColor.red.cgColor,UIColor.green.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 1)
gradient.endPoint = CGPoint(x: 1, y: 0)
gradient.locations = [0,0.5,1]
self.layer.addSublayer(gradient)
}
}
Should look something like this. Maybe your gradient colours would look better.
I want to set an image to a UIImage, but as soon as I set it it the UIImageView gets bigger and goes over other elements.
There is a solution provided here:
Crop UIImage to fit a frame image
But I can not get it to work, I set the properties like in the solution provided.
Maybe somebody can have a look and help me:
Without setting the image:
After setting the image:
class Cell: UICollectionViewCell, CollectionViewCellConfigurable {
var image = UIImageView()
var dateDay = UILabel()
var dateMonth = UILabel()
var title = UILabel()
lazy private var dateContainer: UIView = {
let v = UIView()
v.sv(dateDay, dateMonth)
dateDay.heightAnchor.constraint(equalTo: self.dateMonth.heightAnchor, multiplier: 1).isActive = true
dateDay.leadingAnchor.constraint(equalTo: v.leadingAnchor, constant: 5).isActive = true
dateDay.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: -5).isActive = true
dateDay.topAnchor.constraint(equalTo: v.topAnchor, constant: 15).isActive = true
dateDay.bottomAnchor.constraint(equalTo: dateMonth.topAnchor, constant: -5).isActive = true
dateMonth.heightAnchor.constraint(equalTo: self.dateDay.heightAnchor, multiplier: 1).isActive = true
dateMonth.leadingAnchor.constraint(equalTo: v.leadingAnchor, constant: 5).isActive = true
dateMonth.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: -5).isActive = true
dateMonth.topAnchor.constraint(equalTo: dateDay.bottomAnchor, constant: 5).isActive = true
// dateMonth.bottomAnchor.constraint(greaterThanOrEqualTo: v.bottomAnchor, constant: -5).isActive = true
return v
}()
lazy private var container: UIView = {
return UIView()
}()
func configureCellAtIndexPath(item: Journaling) {
self.image.image = UIImage.baliBeach
self.image.backgroundColor = .green
self.dateDay.text = "16"
self.dateMonth.text = "May"
self.title.text = "Text visible"
}
override init(frame: CGRect) {
super.init(frame:frame)
setUpLayout()
additionalSetUp()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func additionalSetUp() {
backgroundColor = .clear
let colorText: UIColor = .grau
dateDay.textColor = colorText
dateMonth.textColor = colorText
title.textColor = colorText
dateDay.textAlignment = .center
dateMonth.textAlignment = .center
title.textAlignment = .center
image.contentMode = .scaleAspectFill
image.clipsToBounds = true
image.autoresizesSubviews = true
}
func setUpLayout() {
sv(dateContainer, container)
container.sv(image,title)
dateContainer.widthAnchor.constraint(equalToConstant: 45).isActive = true
// dateContainer.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.15).isActive = true
dateContainer.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
dateContainer.trailingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
dateContainer.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
dateContainer.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
// container.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.5).isActive = true
container.leadingAnchor.constraint(equalTo: dateContainer.trailingAnchor, constant: 0).isActive = true
container.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
container.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
container.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
image.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 5).isActive = true
image.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -5).isActive = true
image.topAnchor.constraint(equalTo: self.topAnchor, constant: 15).isActive = true
image.bottomAnchor.constraint(equalTo: title.topAnchor, constant: -5).isActive = true
title.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
title.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: 0).isActive = true
title.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 5).isActive = true
title.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: 0).isActive = true
}
}
You need to higher vertical compression priority of the title label as the imageView is equal it = 750 , so it occupies the space
title.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 751), for: .vertical)
My UILabel is pinned to the top of the cell, just like UIImage but if the text below has f.e. 1 line (its also in UILabel) my top UILabel is in other place.
Here are my constraints and labels declaration. Thanks to anyone who will try to solve my problem :) I tried using sizeToFit method on my UILabels
var albumImage: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
view.contentMode = .scaleAspectFit
return view
}()
var albumName: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.numberOfLines = 0
view.sizeToFit()
return view
}()
var bandName: UILabel = {
let view = UILabel()
view.translatesAutoresizingMaskIntoConstraints = false
view.sizeToFit()
return view
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
drawLayout()
}
required init?(coder aDecoder: NSCoder) {
fatalError("ERROR")
}
func drawLayout(){
let guide = self.safeAreaLayoutGuide
//albumImage
addSubview(albumImage)
addSubview(albumName)
addSubview(bandName)
albumImage.heightAnchor.constraint(equalToConstant: 50).isActive = true
albumImage.widthAnchor.constraint(equalToConstant: 50).isActive = true
albumImage.leadingAnchor.constraint(equalTo: guide.leadingAnchor, constant: 8).isActive = true
albumImage.topAnchor.constraint(equalTo: self.topAnchor, constant: 8).isActive = true
albumImage.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8).isActive = true
//albumTitle
albumName.topAnchor.constraint(equalTo: bandName.bottomAnchor).isActive = true
albumName.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -8).isActive = true
albumName.leadingAnchor.constraint(equalTo: albumImage.trailingAnchor, constant: 8).isActive = true
albumName.trailingAnchor.constraint(equalTo: guide.trailingAnchor, constant: -8).isActive = true
//bandName
bandName.topAnchor.constraint(equalTo: albumImage.topAnchor).isActive = true
bandName.leadingAnchor.constraint(equalTo: albumImage.trailingAnchor, constant: 8).isActive = true
}