This is the code for my custom UILabel:
class RoleLabel: UILabel {
required init?(coder aDecoder: NSCoder) {
super.init(coder:aDecoder)
self.setup()
}
override init(frame:CGRect) {
super.init(frame:frame)
self.setup()
}
override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
func setup(){
numberOfLines = 1
font = UIFont(name:"HelveticaNeue-Bold", size: 16.0)
sizeToFit()
frame = CGRectMake(frame.minX, frame.minY, frame.width + 40, frame.height+5)
backgroundColor = UIColor.blackColor()
textColor = UIColor.whiteColor()
layer.cornerRadius = 5
layer.shadowOffset = CGSize(width: 2, height: 2)
layer.shadowOpacity = 0.7
layer.shadowRadius = 2
drawTextInRect(frame)
let btn = UIButton()
btn.setTitle("X", forState: .Normal)
btn.setTitleColor(UIColor.whiteColor(), forState: .Normal)
btn.frame = CGRectMake(frame.width-20, 1, 20, 23)
addSubview(btn)
}
let topInset = CGFloat(0), bottomInset = CGFloat(0), leftInset = CGFloat(3), rightInset = CGFloat(0)
override func drawTextInRect(rect: CGRect) {
let insets: UIEdgeInsets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}
}
However, since the label resizes according to the text, I need to pass the text as an argument to the initializer.
Is there a way to add this kind of custom parameters?
It doesn't let me add it in override init(frame:CGRect)
To override an init() method in swift you should use the keyword convenience.
As an example you can add the initializer:
convenience init(frame:frame, text:String) {
self.init(frame:frame)
self.text = text
}
Pay attention to the self.init(frame:frame) statement which initializes the UILabel by calling the default initializer.
Related
this is the code where i am configuring the cell.
cell.configure(image: models[indexPath.item].image, tagText: models[indexPath.item].tag, priceIcon: models[indexPath.item].priceIcon, value: models[indexPath.item].price)
and this is my code for cell.
//
// ImageCollectionViewCell.swift
// tr0ve-iOSApp
//
//
//
// ImageCollectionViewCell.swift
// MyCollectionView
//
import UIKit
class ImageCollectionViewCell: UICollectionViewCell {
static let identifier = "ImageCollectionViewCell"
let itemView = UIView()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(itemView)
contentView.clipsToBounds = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
itemView.frame = contentView.bounds
}
override func prepareForReuse() {
super.prepareForReuse()
itemView.subviews.forEach { view in
view.removeFromSuperview()
}
}
func configure (image: UIImage?, tagText: String, priceIcon: UIImage, value: Float){
let imageView = UIImageView(image: image)
let priceTagView = UIView(frame: CGRect(x: 5, y: contentView.frame.size.height-50, width: 60, height: 20))
priceTagView.backgroundColor = .black
let valueLabel = UILabel(frame: CGRect(x: 20, y: 5, width: 35, height: 10))
valueLabel.textColor = .white
valueLabel.text = String(value)
valueLabel.font = UIFont.systemFont(ofSize: 12, weight: .regular)
let priceIconView = UIImageView(frame: CGRect(x: 5, y: 5, width: 10, height: 10))
priceIconView.image = priceIcon
priceTagView.addSubview(priceIconView)
priceTagView.addSubview(valueLabel)
let tag = UILabel(frame: CGRect(x: 100, y: contentView.frame.size.height-50, width: 20, height: 20))
tag.text = tagText
tag.textColor = .white
tag.textAlignment = .center
if tagText == "UC" {
tag.backgroundColor = .green
}
else {
tag.backgroundColor = .blue
}
itemView.addSubview(imageView)
itemView.addSubview(priceTagView)
itemView.addSubview(tag)
}
}
[in this image i want to add subview in cell's bottom, and in tried it using image's frame and by contentView's frame. but it is doing good for some cells and bad for the other ones. and when i scroll everyhing meshes up.1
I need to change alpha value of the button in another class. But the problem is button created as "lazy var" so I can not change that value.
lazy var middleButton: UIButton = {
let button = UIButton(type: .custom)
button.frame.size = CGSize(width: 56, height: 56)
button.layer.cornerRadius = button.frame.width / 2
button.layer.masksToBounds = true
button.backgroundColor = .white
button.setImage(UIImage(named: "iconBasket"), for: .normal)
button.contentMode = .center
button.imageView?.contentMode = .scaleAspectFit
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
button.addTarget(self, action: #selector(btnBasketClicked))
addSubview(button)
return button
}()
I want this button's alpha as 0.2 when view is scrolling. Here is the code
extension ProductListView: UIScrollViewDelegate{
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{
// alpha = 0.2
MyTabBar.shared.scrollDown()
}
else{
// alpha = 1.0
MyTabBar.shared.scrollUp()
}
}
}
func scrollDown(){
middleButton.alpha = 0.2
}
I've tried lots of way but doesn't work. Calling "addSubView()" function in "layoutSubviews()" solve my problem but this causes another problem which my function "basketButtonClicked()" are not called. I used Delegate pattern and here it is.
protocol BasketButtonDelegate: class {
func basketButtonClicked()
}
#objc private func btnBasketClicked(_ sender: UIButton!){
delegate?.basketButtonClicked()
}
override func layoutSubviews() {
super.layoutSubviews()
addSubview(middleButton)
}
When I call "addSubView" function in "layoutSubviews()", "basketbuttonClicked" never called.
extension TabCoordinator : BasketButtonDelegate
{
func basketButtonClicked(){
log.debug("basketButtonClicked")
let coor = CartCoordinator(navigationController, hidesBar: true)
childCoordinators.append(coor)
coor.start()
}
}
(I assigned delegate so the problem is not about it.)
A bit complicated but I hope we can figure it out.
You need to add protocol to your MyTabBar class . It should be like this
class MyTabBar {
static var shared = MyTabBar()
weak var delegate : abc?
func scrollDown(){
delegate?.xyz()
}
}
protocol abc : AnyObject {
func xyz()
}
And in your class
class btnView : UIView , abc{
lazy var middleButton: UIButton = {
let button = UIButton(type: .custom)
button.frame.size = CGSize(width: 56, height: 56)
button.layer.cornerRadius = button.frame.width / 2
button.layer.masksToBounds = true
button.backgroundColor = .red
button.contentMode = .center
button.imageView?.contentMode = .scaleAspectFit
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
button.addTarget(self, action: #selector(btnBasketClicked), for: .touchUpInside)
return button
}()
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
#objc func btnBasketClicked(){
print("Im here")
}
func addMiddleButton(){
self.addSubview(middleButton)
}
func alphaaa(){
self.middleButton.alpha = 0.2
}
func xyz() {
self.alphaaa()
}
}
Last , in your ProductListView create and instance of your view , or if you add with autolayout just call 2. function in your viewDidLoad
var viewwww = btnView(frame: CGRect(x: 10, y: 10, width: 100, height: 100))
viewwww.addMiddleButton() // call to add btn to custom view
and extension
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.panGestureRecognizer.translation(in: scrollView).y < 0{
// alpha = 0.2
MyTabBar.shared.delegate = viewwww
MyTabBar.shared.scrollDown()
}
else{
// alpha = 1.0
MyTabBar.shared.scrollUp()
}
}
I'm using a placeHolder extension to give padding to the placeholder. But when I apply this class to my input field it doesn't show the clear button even if I select "Appears while editing" on the storyboard.
Can someone tell me how to fix it?
import UIKit
class textFiledplaceholder: UITextField {
static let font_size : CGFloat = 16
static let leftPadding : CGFloat = 15
static let righPadding : CGFloat = 15
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.comminIt()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.comminIt()
}
func comminIt()
{
borderStyle = .none
backgroundColor = .white
// layer.masksToBounds = true
setLeftPaddingPoints(textFiledplaceholder.leftPadding)
setRightPaddingPoints(textFiledplaceholder.righPadding)
}
}
extension UITextField {
func setLeftPaddingPoints(_ amount:CGFloat){
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.leftView = paddingView
self.leftViewMode = .always
}
func setRightPaddingPoints(_ amount:CGFloat) {
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: amount, height: self.frame.size.height))
self.rightView = paddingView
self.rightViewMode = .always
}
}
You can not use rightview and clearbutton together. And if you are going to use a clear button then I don't think there is any use of right padding. Remove right padding and it will resolve your issue.
I created a custom UIButton with this initialiser :
class CustomButton : UIButton{
override init(frame: CGRect) {
super.init(frame: frame)
setUpButtoninClass(frame)
addTarget(self, action: #selector(handleTap), for:.touchUpInside )
}
fileprivate func setUpButtoninClass(_ frame: CGRect) {
let padding : CGFloat = 16
self.frame = frame
layer.shadowColor = UIColor.darkGray.cgColor
layer.shadowOpacity = 0.3
layer.shadowOffset = .zero
layer.shadowRadius = 10
layer.cornerRadius = frame.width/2
backgroundColor = UIColor(white: 0.9, alpha: 1)
let buttonView = UIView(frame: frame)
buttonView.layer.cornerRadius = frame.width/2
buttonView.backgroundColor = .white
addSubview(buttonView)
let imageView = UIImageView(image: UIImage(named: "pen")?.withRenderingMode(.alwaysTemplate))
imageView.tintColor = UIColor(white: 0.7, alpha: 1)
buttonView.addSubview(imageView)
imageView.anchor(top: buttonView.topAnchor, leading: buttonView.leadingAnchor, bottom: buttonView.bottomAnchor, trailing: buttonView.trailingAnchor, padding: UIEdgeInsets.init(top: padding, left: padding, bottom: padding, right: padding))
}
#objc func handleTap(){
print("I'm here")
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}}
In the initialiser I'm adding a target but when I actually initialise the custom button in the VC the #selector method (handleTap) is not called.
This is the implementation of custom Button in VC:
class ViewController: UIViewController {
let circularButton = CustomButton(frame: CGRect(x: 0, y: 0, width: 70, height: 70))
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(circularButton)
circularButton.center = view.center
}
I also tried to add the target when initialising the CustomButton in the VC but nothing changed.
I would like to know where I'm making a mistake in setting up the button.
EDIT 1 :
this is the Debug View Hierarchy
OMG, after debug your code, buttonView and imageView is on the top. Button is behide. You can set the color to debug it more easily. Delete 2 views above make your code works perfectly
I think it's your fault here,
Touch is not detected because you added an ImageView to the top of UIButton.
Try this, or this one,
buttonView.isUserInteractionEnabled = true
imageView.isUserInteractionEnabled = true
I have been creating a UILabel class called RPLabel, which is supposed to shorten all of my long list of programmatically set labels. This is the class code:
class RPLabel: UILabel {
// moneyTitle.frame = CGRect(x: 50, y: -50, width:XX, height: 35) //
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.setup()
self.testForLabelType()
}
enum labelTypeEnumeration {
case title, subtitle
}
var labelType = labelTypeEnumeration.title
override init(frame: CGRect){
super.init(frame: frame)
self.setup()
}
override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
func setup(){
self.text = self.text
self.textColor = self.textColor
self.font = self.font
self.layer.display()
}
func testForLabelType() {
switch labelType {
case .title:
setupTitle()
print("setupTitle")
case .subtitle:
setupSubtitle()
print("setupSubtitle")
}
}
func setupTitle(){
self.font = UIFont.boldSystemFont(ofSize: 12)
self.textColor = UIColor.secondaryColor()
self.textAlignment = .left
}
func setupSubtitle(){
self.font = UIFont.boldSystemFont(ofSize: 18)
self.textColor = UIColor.rgb(red: 200, green: 200, blue: 200)
self.textAlignment = .left
}
}
To make a label, I use the following piece of code:
var moneyTitle = RPLabel()
moneyTitle.labelType = .title
moneyTitle.testForLabelType()
moneyTitle.text = "MONEY"
moneyTitle.frame = CGRect(x: 50, y: -50, width:XX, height: 35)
The issue that I have is that I would like to set the labelType to .title without having to write moneyTitle.testForLabelType(). In other words, I would like for that function to run automatically in the class. An alternative I would not like would be inserting the parameter in the init, so please avoid telling me to do so, thanks.
You can use didSet:
didSet is called immediately after the new value is stored.
var labelType = labelTypeEnumeration.title {
didSet {
testForLabelType()
}
}