Using Auto Layout to align a custom UIView to the view programatically - swift

I am trying to align a custom UIView to the center of view using auto layout but I am getting a blank screen.
Please can someone advise on where my code is incorrect?
My Controller's code:
import UIKit
class TestViewController: UIViewController{
var margin: UILayoutGuide!
override func viewDidLoad() {
super.viewDidLoad()
margin = self.view.layoutMarginsGuide
let size = CGRect.init(x: 0, y: 0, width: 200, height: 100)
let sq1 = Square.init(frame: size, color: UIColor.blue)
view.addSubview(sq1)
sq1.translatesAutoresizingMaskIntoConstraints = false
sq1.centerXAnchor.constraint(equalTo: margin.centerXAnchor).isActive = true
sq1.topAnchor.constraint(greaterThanOrEqualTo: margin.topAnchor, constant: 20).isActive = true
sq1.leadingAnchor.constraint(greaterThanOrEqualTo: margin.leadingAnchor, constant: 20).isActive = true
sq1.trailingAnchor.constraint(greaterThanOrEqualTo: margin.trailingAnchor, constant: 20).isActive = true
}
}
My Custom View's code:
class Square: UIView{
init(frame: CGRect, color: UIColor) {
super.init(frame: frame)
makeSquare(frame: frame, colour: color)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func makeSquare(frame: CGRect, colour: UIColor){
self.layer.frame = self.bounds
self.layer.backgroundColor = colour.cgColor
}
}

You need a height constraint , also don't mix frame layout with auto layout you should use either of them
sq1.heightAnchor.constraint(equalToConstant:200).isActive = true
Also if you set leading and trailing
sq1.leadingAnchor.constraint(greaterThanOrEqualTo: margin.leadingAnchor, constant: 20).isActive = true
sq1.trailingAnchor.constraint(greaterThanOrEqualTo: margin.trailingAnchor, constant: 20).isActive = true
then no need for a centerX
sq1.centerXAnchor.constraint(equalTo: margin.centerXAnchor).isActive = true
NSLayoutConstraint.activate([
sq1.topAnchor.constraint(equalTo: margin.topAnchor, constant: 20),
sq1.leadingAnchor.constraint(equalTo: margin.leadingAnchor, constant: 20),
sq1.trailingAnchor.constraint(equalTo: margin.trailingAnchor, constant: -20),
sq1.heightAnchor.constraint(equalToConstant: 200)
])

After some small additions:
class Square: UIView {
init(color: UIColor) {
// The view is ignored with auto layout.
super.init(frame: .zero)
backgroundColor = color
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Then in the viewDidLoad function:
override func viewDidLoad() {
super.viewDidLoad()
let sq = Square(color: .orange)
sq.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(sq)
sq.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
sq.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
// -40 to compensate for the leading and trailing.
sq.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1, constant: -40).isActive = true
sq.heightAnchor.constraint(equalTo: sq.widthAnchor).isActive = true
// Do any additional setup after loading the view.
}
I've taken the freedom to set the height equal to the width, as you create a square, but not sure if you want that. Hope this helps!

try it
class Square: UIView {
func setColor(colour: UIColor){
self.backgroundColor = colour
}
}
call this func in ViewDidLoad
func initView() {
self.view.backgroundColor = .red
margin = self.view.layoutMarginsGuide
let sq1 = Square()
view.addSubview(sq1)
sq1.translatesAutoresizingMaskIntoConstraints = false
sq1.centerXAnchor.constraint(equalTo: margin.centerXAnchor).isActive = true
sq1.topAnchor.constraint(greaterThanOrEqualTo: margin.topAnchor, constant: 20).isActive = true
sq1.widthAnchor.constraint(equalToConstant: 200).isActive = true
sq1.heightAnchor.constraint(equalToConstant: 200).isActive = true
sq1.setColor( colour: UIColor.blue)
}
result

Related

Increase UIView Height Programmatically Based on Changing SubView Height

I have been unable to figure out how to solve this issue of mine. I tried to follow the answer from this post. How to change UIView height based on elements inside it
Like the post answer says to do, I have:
set autolayout constraints between UIContainerView top to the UITextView top and UIContainerView bottom to the UITextView bottom (#1)
set height constraint on the text view (#2) and change its constant when resizing the text view (#3)
I have to do this all programmatically. I first set the frame for the container view and give it a specified height. I'm not sure if that is okay too. I also add (#1) in viewDidLoad and am unsure if that's correct.
The text view is not able to increase height either with the current constraints (it is able to if I remove the topAnchor constraint but the container view still doesn't change size).
class ChatController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
lazy var containerView: UIView = {
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height * 0.075)
return containerView
}()
lazy var textView: UITextView = {
let textView = UITextView()
textView.text = "Enter message..."
textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints = false
textView.delegate = self
return textView
}()
override func viewDidLoad() {
super.viewDidLoad()
...
textViewDidChange(self.textView)
addContainerSubViews()
(#1)
containerView.topAnchor.constraint(equalTo: self.textView.topAnchor, constant: -UIScreen.main.bounds.size.height * 0.075 * 0.2).isActive = true
containerView.bottomAnchor.constraint(equalTo: self.textView.bottomAnchor, constant: UIScreen.main.bounds.size.height * 0.075 * 0.2).isActive = true
}
func addContainerSubViews() {
let height = UIScreen.main.bounds.size.height
let width = UIScreen.main.bounds.size.width
let containerHeight = height * 0.075
...//constraints for imageView and sendButton...
containerView.addSubview(self.textView)
self.textView.leftAnchor.constraint(equalTo: imageView.rightAnchor, constant: width/20).isActive = true
self.textView.rightAnchor.constraint(equalTo: sendButton.leftAnchor, constant: -width/20).isActive = true
(#2)
self.textView.heightAnchor.constraint(equalToConstant: containerHeight * 0.6).isActive = true
}
override var inputAccessoryView: UIView? {
get {
return containerView
}
}
(#3)
func textViewDidChange(_ textView: UITextView) {
let size = CGSize(width: view.frame.width, height: .infinity)
let estimatedSize = textView.sizeThatFits(size)
textView.constraints.forEach { (constraint) in
if constraint.firstAttribute == .height {
constraint.constant = estimatedSize.height
}
}
}
You can do this all with auto-layout / constraints. Because a UITextView with scrolling disabled will "auto-size" its height based on the text, no need to calculate height and change constraint constant.
Here's an example -- it's from a previous answer, modified to include your image view and send button:
class ViewController: UIViewController {
let testLabel: InputLabel = InputLabel()
override func viewDidLoad() {
super.viewDidLoad()
let instructionLabel = UILabel()
instructionLabel.textAlignment = .center
instructionLabel.text = "Tap yellow label to edit..."
let centeringFrameView = UIView()
// label properties
let fnt: UIFont = .systemFont(ofSize: 32.0)
testLabel.isUserInteractionEnabled = true
testLabel.font = fnt
testLabel.adjustsFontSizeToFitWidth = true
testLabel.minimumScaleFactor = 0.25
testLabel.numberOfLines = 2
testLabel.setContentHuggingPriority(.required, for: .vertical)
let minLabelHeight = ceil(fnt.lineHeight)
// so we can see the frames
centeringFrameView.backgroundColor = .red
testLabel.backgroundColor = .yellow
[centeringFrameView, instructionLabel, testLabel].forEach {
$0.translatesAutoresizingMaskIntoConstraints = false
}
view.addSubview(instructionLabel)
view.addSubview(centeringFrameView)
centeringFrameView.addSubview(testLabel)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// instruction label centered at top
instructionLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
instructionLabel.centerXAnchor.constraint(equalTo: g.centerXAnchor),
// centeringFrameView 20-pts from instructionLabel bottom
centeringFrameView.topAnchor.constraint(equalTo: instructionLabel.bottomAnchor, constant: 20.0),
// Leading / Trailing with 20-pts "padding"
centeringFrameView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
centeringFrameView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
// test label centered vertically in centeringFrameView
testLabel.centerYAnchor.constraint(equalTo: centeringFrameView.centerYAnchor, constant: 0.0),
// Leading / Trailing with 20-pts "padding"
testLabel.leadingAnchor.constraint(equalTo: centeringFrameView.leadingAnchor, constant: 20.0),
testLabel.trailingAnchor.constraint(equalTo: centeringFrameView.trailingAnchor, constant: -20.0),
// height will be zero if label has no text,
// so give it a min height of one line
testLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: minLabelHeight),
// centeringFrameView height = 3 * minLabelHeight
centeringFrameView.heightAnchor.constraint(equalToConstant: minLabelHeight * 3.0)
])
// to handle user input
testLabel.editCallBack = { [weak self] str in
guard let self = self else { return }
self.testLabel.text = str
}
testLabel.doneCallBack = { [weak self] in
guard let self = self else { return }
// do something when user taps done / enter
}
let t = UITapGestureRecognizer(target: self, action: #selector(self.labelTapped(_:)))
testLabel.addGestureRecognizer(t)
}
#objc func labelTapped(_ g: UITapGestureRecognizer) -> Void {
testLabel.becomeFirstResponder()
testLabel.inputContainerView.theTextView.text = testLabel.text
testLabel.inputContainerView.theTextView.becomeFirstResponder()
}
}
class InputLabel: UILabel {
var editCallBack: ((String) -> ())?
var doneCallBack: (() -> ())?
override var canBecomeFirstResponder: Bool {
return true
}
override var canResignFirstResponder: Bool {
return true
}
override var inputAccessoryView: UIView? {
get { return inputContainerView }
}
lazy var inputContainerView: CustomInputAccessoryView = {
let v = CustomInputAccessoryView()
v.editCallBack = { [weak self] str in
guard let self = self else { return }
self.editCallBack?(str)
}
v.doneCallBack = { [weak self] in
guard let self = self else { return }
self.resignFirstResponder()
}
return v
}()
}
class CustomInputAccessoryView: UIView, UITextViewDelegate {
var editCallBack: ((String) -> ())?
var doneCallBack: (() -> ())?
let theTextView: UITextView = {
let tv = UITextView()
tv.isScrollEnabled = false
tv.font = .systemFont(ofSize: 16)
tv.autocorrectionType = .no
tv.returnKeyType = .done
return tv
}()
let imgView: UIImageView = {
let v = UIImageView()
v.contentMode = .scaleAspectFit
v.clipsToBounds = true
return v
}()
let sendButton: UIButton = {
let v = UIButton()
return v
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .lightGray
autoresizingMask = [.flexibleHeight, .flexibleWidth]
if let img = UIImage(named: "testImage") {
imgView.image = img
} else {
imgView.backgroundColor = .systemBlue
}
let largeConfig = UIImage.SymbolConfiguration(pointSize: 22, weight: .regular, scale: .large)
let buttonImg = UIImage(systemName: "paperplane.fill", withConfiguration: largeConfig)
sendButton.setImage(buttonImg, for: .normal)
[theTextView, imgView, sendButton].forEach { v in
addSubview(v)
v.translatesAutoresizingMaskIntoConstraints = false
}
// if we want to see the image view and button frames
//[imgView, sendButton].forEach { v in
// v.backgroundColor = .systemYellow
//}
NSLayoutConstraint.activate([
// constrain image view 40x40 with 8-pts leading
imgView.widthAnchor.constraint(equalToConstant: 40.0),
imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor),
imgView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8.0),
// constrain image view 40x40 with 8-pts trailing
sendButton.widthAnchor.constraint(equalToConstant: 40.0),
sendButton.heightAnchor.constraint(equalTo: sendButton.widthAnchor),
sendButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8.0),
// constrain text view with 10-pts from
// image view trailing
// send button leading
theTextView.leadingAnchor.constraint(equalTo: imgView.trailingAnchor, constant: 10),
theTextView.trailingAnchor.constraint(equalTo: sendButton.leadingAnchor, constant: -10),
// constrain image view and button
// centered vertically
// at least 8-pts top and bottom
imgView.centerYAnchor.constraint(equalTo: centerYAnchor),
sendButton.centerYAnchor.constraint(equalTo: centerYAnchor),
imgView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: 8.0),
sendButton.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: 8.0),
imgView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -8.0),
sendButton.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor, constant: -8.0),
// constrain text view 8-pts top/bottom
theTextView.topAnchor.constraint(equalTo: topAnchor, constant: 8.0),
theTextView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8.0),
])
theTextView.delegate = self
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text == "\n") {
textView.resignFirstResponder()
doneCallBack?()
}
return true
}
func textViewDidChange(_ textView: UITextView) {
editCallBack?(textView.text ?? "")
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var intrinsicContentSize: CGSize {
return .zero
}
}
Output:

Change view with Segment View Control

I have created a view in my View controller which has UISegmentControl and a UIScrollView
let segmentControl : UISegmentedControl = {
let segmentItems = ["Personal","Statistics","Calendar"]
let segmentControl = UISegmentedControl(items: segmentItems)
segmentControl.selectedSegmentIndex = 0
segmentControl.addTarget(self, action: #selector(selectIn(sender:)), for: .valueChanged)
segmentControl.translatesAutoresizingMaskIntoConstraints = false
return segmentControl
}()
let subView : UIScrollView = {
let view = UIScrollView()
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
In viewDidLoad I added
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
view.addSubview(segmentControl)
view.addSubview(subView)
setLayout()
}
and added layout as follows
func setLayout(){
NSLayoutConstraint.activate([
segmentControl.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
segmentControl.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20),
segmentControl.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20),
segmentControl.heightAnchor.constraint(equalToConstant: 30),
subView.topAnchor.constraint(equalTo: segmentControl.bottomAnchor, constant: 10),
subView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20),
subView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20),
subView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
}
and tried to add PersonalView (UIView) when any segmentControl is pressed
#objc func selectIn(sender: UISegmentedControl){
subView.addSubview(pvc)
}
My personalView is as follows
class PersonalView: UIView, UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource {
let tempValueForTable : Int = 10
let todayLabel : UILabel = {
let label = UILabel()
label.text = "Today"
label.font = .montserratSemiBold
label.textAlignment = .center
label.backgroundColor = .green
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(todayLabel)
setLayout()
}
private func setLayout(){
NSLayoutConstraint.activate([
todayLabel.topAnchor.constraint(equalTo: self.topAnchor),
todayLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20),
todayLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20),
todayLabel.heightAnchor.constraint(equalToConstant: 25),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}}
Still I am not able to get view and in further update I need to add more view in same ScrollView
1.when you are using auto layout constraints you must set this false after add.
SomeView.translatesAutoresizingMaskIntoConstraints = false
2.After you add your subView you must set its constraints and call view.layoutIfNeeded()
subView.addSubview(pvc)
pvc.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
pvc.trailingAnchor.constraint(equalTo: subView.trailingAnchor),
pvc.leadingAnchor.constraint(equalTo: subView.leadingAnchor),
pvc.topAnchor.constraint(equalTo: subView.topAnchor),
pvc.bottomAnchor.constraint(equalTo: subView.bottomAnchor),
])
view.layoutIfNeeded()

Custom Button Subviews not Showing

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

Cannot override with a stored property 'leadingConstraint' , Overriding non-open var outside of its defining module xcode 10

I'm getting this weird error. My Project was working fine and all of a sudden I got these errors. The errors indicated by Xcode:
Cannot override with a stored property 'leadingConstraint'
Overriding non-open var outside of its defining module
I've defined a constraint variable in UITableViewCell, on which it's giving error.
I tried
clean the build folder.
Restarted the Xcode but it's still giving me
that error.
Error
Cell:
import UIKit
class ReceiverChatImageCell: UITableViewCell {
let bubbleBackgroundView: UIView = {
let v = UIView()
v.backgroundColor = UIColor.darkGray
v.layer.cornerRadius = 5
v.layer.masksToBounds = true
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
public let chatImage: UIImageView = {
let v = UIImageView()
v.contentMode = .scaleAspectFill
v.translatesAutoresizingMaskIntoConstraints = false
v.clipsToBounds = true
return v
}()
var maxMessageLength: CGFloat = 250
var leadingConstraint: NSLayoutConstraint?
var chatMessage: ChatModel! {
didSet {
profileImageView.loadImage(string: chatMessage.imageUrl)
chatImage.loadImage(string: chatMessage.chatImageUrl)
}
}
public let profileImageView: UIImageView = {
let v = UIImageView()
v.image = #imageLiteral(resourceName: "babs")
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleAspectFill
v.clipsToBounds = true
v.layer.cornerRadius = 20
return v
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit(){
backgroundColor = .clear
addSubview(profileImageView)
addSubview(bubbleBackgroundView)
addSubview(chatImage)
let available: CGFloat = UIScreen.main.bounds.width - 100
if maxMessageLength > available{
maxMessageLength = available - 50
print("Available Space \(maxMessageLength)")
}
// lets set up some constraints for our image
let constraints = [
profileImageView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0),
profileImageView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
profileImageView.widthAnchor.constraint(equalToConstant: 40),
profileImageView.heightAnchor.constraint(equalToConstant: 40),
chatImage.topAnchor.constraint(equalTo: topAnchor, constant: 8),
chatImage.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -24),
chatImage.widthAnchor.constraint(lessThanOrEqualToConstant: maxMessageLength),
chatImage.heightAnchor.constraint(lessThanOrEqualToConstant: 250),
bubbleBackgroundView.topAnchor.constraint(equalTo: chatImage.topAnchor, constant: -8),
bubbleBackgroundView.leadingAnchor.constraint(equalTo: chatImage.leadingAnchor, constant: -16),
bubbleBackgroundView.bottomAnchor.constraint(equalTo: chatImage.bottomAnchor, constant: 8),
bubbleBackgroundView.trailingAnchor.constraint(equalTo: chatImage.trailingAnchor, constant: 16),
]
NSLayoutConstraint.activate(constraints)
leadingConstraint = chatImage.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60)
leadingConstraint?.isActive = true
}
}
I haven't used this variable outside the cell.
How can I solve this problem?

creating custom UITextfield

how do i make custom UITextfield? i have created class with uitextfield as a subclass then i added label it shows up, but the border(UIView) are not showing up here is the code
import UIKit
class borderedTextField: UITextField{
let viewz:UIView! = UIView()
var border:UIView! = UIView()
var name:UILabel! = UILabel()
override func draw(_ rect: CGRect) {
self.addSubview(viewz)
}
override func layoutSubviews() {
backgroundColor = UIColor.green
}
func placement(){
border.frame.size.height = 15
border.backgroundColor = UIColor.black
border.translatesAutoresizingMaskIntoConstraints = false
viewz.addSubview(border)
border.heightAnchor.constraint(equalToConstant: 15).isActive = true
border.widthAnchor.constraint(equalToConstant: 100)
border.leftAnchor.constraint(equalTo: viewz.leftAnchor, constant: 10).isActive = true
border.bottomAnchor.constraint(equalTo: viewz.bottomAnchor, constant: -5).isActive = true
name.text = "whatt"
name.textAlignment = .left
name.textColor = UIColor.black
name.translatesAutoresizingMaskIntoConstraints = false
viewz.addSubview(name)
name.widthAnchor.constraint(equalToConstant: 100)
name.heightAnchor.constraint(equalToConstant: 50)
name.leftAnchor.constraint(equalTo: viewz.leftAnchor, constant: 5).isActive = true
name.topAnchor.constraint(equalTo: viewz.topAnchor, constant: 10).isActive = true
}
}
and i called it programatically (without storyboard) please let me know how to solve this problem without using storyboard i need it to be full code.
import UIKit
class signViewController: UIViewController,UITextFieldDelegate {
var animText:borderedTextField!
override func viewDidLoad() {
super.viewDidLoad()
let animText = borderedTextField()
animText.delegate = self
animText.placeholder = "click here"
animText.placement()
animText.frame = CGRect(x: 100, y: 500, width: 200, height: 90)
view.addSubview(animText)
}
}
You have to add init
override init (frame : CGRect) {
super.init(frame : frame)
self.placement()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.placement()
}
Also width of border is not active
border.widthAnchor.constraint(equalToConstant: 100).active = true
for name
name.widthAnchor.constraint(equalToConstant: 100).active = true
name.heightAnchor.constraint(equalToConstant: 50).active = true
Edit
border.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true
border.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -5).isActive = true