Adding subview is not working - ios

I'm trying to make a popUp view.
Here I have
let popOver = UIView()
popOver.hidden = true
popOver.frame = CGRectMake(self.view.frame.width / 2 - 150, self.view.frame.height / 2 - 150, 250, 250)
popOver.backgroundColor = UIColor.whiteColor()
let lbl = UILabel()
lbl.text = "blablabla"
lbl.backgroundColor = UIColor.redColor()
lbl.textColor = UIColor.yellowColor()
popOver.addSubview(lbl)
lbl.center = popOver.center
popOver.bringSubviewToFront(lbl)
self.view.addSubview(popOver)
popOver.center = self.view.center
popOver.layer.cornerRadius = 9
UIView.animateWithDuration(2.0, animations: {
self.popOver.hidden = false
})
}
Everything is ok except that the label is now shown any time I try to execute my application. I see only white frame:
What my mistake is?

try this
let popOver = UIView()
popOver.hidden = true
popOver.frame = CGRectMake(self.view.frame.width / 2 - 150, self.view.frame.height / 2 - 150, 250, 250)
popOver.backgroundColor = UIColor.whiteColor()
popOver.center = self.view.center
popOver.layer.cornerRadius = 9
self.view.addSubview(popOver)
let lbl = UILabel()
lbl.text = "blablabla"
lbl.backgroundColor = UIColor.redColor()
lbl.textColor = UIColor.yellowColor()
lbl.frame = CGRectMake((popOver.frame.size.width / 2)-50, (popOver.frame.size.height / 2)-50, 100,100)
//lbl.center = popOver.center
popOver.addSubview(lbl)
popOver.bringSubviewToFront(lbl)
UIView.animateWithDuration(1.0, animations: {
popOver.hidden = false
})
the output is

You are wrong at the position of the label
let lbl = UILabel()
lbl.frame = CGRectMake(0, 0, 25, 25)
lbl.text = "blablabla"
lbl.backgroundColor = UIColor.redColor()
lbl.textColor = UIColor.yellowColor()
popOver.addSubview(lbl)
//lbl.center = popOver.center
lbl.center = CGPointMake(popOver.frame.width / 2, popOver.frame.height/2)

Related

Set subviews to correct dimensions after parent view has scaled

I am creating a UIView programtically that is scaled and translated to the center of my view. I am then adding subviews (UILabel's) to that view programatically and the issue I have encountered is that the text for the UILabel's is stretched and difficult to read. I have tried to set autoresizeSubviews = false however this did not have any effect. I have also tried setting the number of lines but this did not have any affect either. I wanted to know if there was a possible solution to this problem that perhaps I am overlooking. Below is my code...
Here i instantiate each UI object to be used on view including view itself
//create lazy vars for UIView that is instantiated until it is initialized
lazy var enlargedView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.white
view.layer.cornerRadius = 12.0
view.clipsToBounds = true
return view
}()
lazy var profileImageView: UIImageView = {
let imageView = UIImageView()
imageView.frame = CGRect(x: self.enlargedView.center.x, y: self.enlargedView.bounds.origin.y + 20.0, width: self.enlargedView.bounds.width * 0.4, height: self.enlargedView.bounds.width * 0.4)
imageView.layer.cornerRadius = imageView.frame.width / 2
imageView.clipsToBounds = true
imageView.layer.borderColor = UIColor.black.cgColor
imageView.layer.borderWidth = 1.0
imageView.contentMode = .scaleAspectFit
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
lazy var usernameLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.textColor = UIColor.black
let font = UIFont(name: Constants.Fonts.GILL_SANS_SEMIBOLD, size: 8.0)
let fontMetrics = UIFontMetrics(forTextStyle: .body)
label.font = fontMetrics.scaledFont(for: font!)
label.textAlignment = .center
//label.sizeToFit()
label.translatesAutoresizingMaskIntoConstraints = false
return label
} ()
lazy var userDataLabel: UILabel = {
let label = UILabel()
//creates implicit height for label
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.textColor = UIColor.black
let font = UIFont(name: Constants.Fonts.GILL_SANS, size: 10.0)
let fontMetrics = UIFontMetrics(forTextStyle: .body)
label.font = fontMetrics.scaledFont(for: font!)
label.textAlignment = .center
label.sizeToFit()
label.translatesAutoresizingMaskIntoConstraints = false
return label
} ()
Next I create animation for view to scale and translate once a collectionView cell is tapped
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SearchCell", for: indexPath) as! SearchCell
let currentFrame = cell.frame
let selectedUser = userNameArr[indexPath.row]
enlargedView.frame = currentFrame
let backgroundView = UIView(frame: self.view.bounds)
backgroundView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseOut, animations: {
self.view.addSubview(self.enlargedView)
//translate view to center of screen
self.enlargedView.center = CGPoint(x: self.view.bounds.midX, y: self.view.bounds.midY)
//while view is being translated background subview should be inserted
self.view.insertSubview(backgroundView, belowSubview: self.enlargedView)
self.enlargedView.transform = CGAffineTransform(scaleX: 2.5, y: 2.5)
}) { (viewWasEnlarged) in
if viewWasEnlarged {
if let profile = selectedUser.user_photo_url {
self.profileImageView.kf.setImage(with: URL(string:Constants.Server.MEDIA_URL + profile))
} else {
self.profileImageView.image = UIImage(named: "user_icon")
}
self.enlargedView.addSubview(self.profileImageView)
self.profileImageView.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.top.equalTo(self.enlargedView.snp.top).offset(20.0)
make.width.equalTo(self.enlargedView.snp.width).multipliedBy(0.4)
make.height.equalTo(self.enlargedView.snp.width).multipliedBy(0.4)
}
//USERNAME label
self.usernameLabel.text = selectedUser.user_name!
self.enlargedView.addSubview(self.usernameLabel)
self.usernameLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.width.equalTo(self.enlargedView.snp.width).multipliedBy(0.9)
make.top.equalTo(self.profileImageView.snp.bottom).offset(5.0)
}
//reset enlarged view back to original value
self.usernameLabel.transform = CGAffineTransform.identity
//USER DATA label
var userAge = ""
var userRelationshipStatus = ""
if let userYear = selectedUser.user_birthday {
let yr = self.calendar.dateComponents([.year], from: userYear).year
userAge = "\(yr!)"
}
if let status = selectedUser.user_stats {
userRelationshipStatus = status
}
self.userDataLabel.text = userAge + " | " + userRelationshipStatus
self.enlargedView.addSubview(self.userDataLabel)
self.userDataLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.width.equalTo(self.enlargedView.snp.width).multipliedBy(0.2)
make.top.equalTo(self.usernameLabel.snp.bottom).offset(3.0)
}
//create label to show HUB as well
//create bio
//show Path??
}
}
The imageView is unaffected however the text itself is not reflected correctly

How do I change what is shown when the UISegmentedControl index is changed?

I have a small issue with my segmented controller and trying to change the views shown to the user when clicking a new index. I have code set to show text-boxes that the user would type into when the index is changed. One issue is that I want to place text-boxes under the segmented controller evenly and the other issue is that when I click a new index in the controller, the prior text box is still on the screen, but I need it to show just the text box correlating to the specific index that is chosen. The code is shown below where I created the segment controller and handled the switch of indexes as well as the creation of the text-boxes.
let segmentedControl: UISegmentedControl = {
let sc = UISegmentedControl(items: ["Inventory", "Sale", "Expense"])
sc.selectedSegmentIndex = 0
sc.layer.cornerRadius = 9
sc.layer.borderWidth = 1
sc.layer.borderColor = UIColor.lightGray.cgColor
sc.layer.masksToBounds = true
sc.addTarget(self, action: #selector(handleSegmentChange), for: .valueChanged)
return sc
}()
//function to handle click of segmented control buttons
#objc fileprivate func handleSegmentChange(sender: UISegmentedControl){
print(segmentedControl.selectedSegmentIndex)
switch segmentedControl.selectedSegmentIndex{
case 0:
view.addSubview(myProduct)
case 1:
view.addSubview(myRetail)
default:
view.addSubview(myExpense)
break
}
}
let myProduct : UITextField = {
let mp = UITextField(frame: CGRect(x: 10, y: 320, width: 300, height: 10))
mp.placeholder = "Enter Product name"
mp.borderStyle = UITextField.BorderStyle.line
mp.backgroundColor = .white
mp.textColor = .cyan
return mp
}();
let myRetail : UITextField = {
let mp = UITextField(frame: CGRect(x: 10, y: 320, width: 300, height: 20))
mp.placeholder = "Enter Retail price"
mp.borderStyle = UITextField.BorderStyle.line
mp.backgroundColor = .white
mp.textColor = .cyan
return mp
}();
let myExpense : UITextField = {
let mp = UITextField(frame: CGRect(x: 10, y: 320, width: 300, height: 30))
mp.placeholder = "Enter Expense name"
mp.borderStyle = UITextField.BorderStyle.line
mp.backgroundColor = .white
mp.textColor = .cyan
return mp
}();
Most of the solutions I have seen are outdated, which is why I am posting my own version here. Thanks in advance for help anyone can provide.
You can set tag for each UITextField as below,
let myProduct : UITextField = {
let mp = UITextField(frame: CGRect(x: 10, y: 320, width: 300, height: 10))
mp.placeholder = "Enter Product name"
mp.borderStyle = UITextField.BorderStyle.line
mp.backgroundColor = .white
mp.textColor = .cyan
mp.tag = 11
return mp
}()
let myRetail : UITextField = {
let mp = UITextField(frame: CGRect(x: 10, y: 320, width: 300, height: 20))
mp.placeholder = "Enter Retail price"
mp.borderStyle = UITextField.BorderStyle.line
mp.backgroundColor = .white
mp.textColor = .cyan
mp.tag = 12
return mp
}()
let myExpense : UITextField = {
let mp = UITextField(frame: CGRect(x: 10, y: 320, width: 300, height: 30))
mp.placeholder = "Enter Expense name"
mp.borderStyle = UITextField.BorderStyle.line
mp.backgroundColor = .white
mp.textColor = .cyan
mp.tag = 13
return mp
}()
and then inside handleSegmentChange, remove any view with that tag before adding a new one as below,
//function to handle click of segmented control buttons
#objc fileprivate func handleSegmentChange(sender: UISegmentedControl){
print(segmentedControl.selectedSegmentIndex)
[11, 12, 13].forEach { self.view.viewWithTag($0)?.removeFromSuperview() }
switch segmentedControl.selectedSegmentIndex {
case 0:
view.addSubview(myProduct)
case 1:
view.addSubview(myRetail)
default:
view.addSubview(myExpense)
}
}
For the position issue, you haven't set any frame to UISegmentControl. You can set frame as below to get the result shown,
let segmentedControl: UISegmentedControl = {
let sc = UISegmentedControl(items: ["Inventory", "Sale", "Expense"])
sc.selectedSegmentIndex = 0
sc.layer.cornerRadius = 9
sc.layer.borderWidth = 1
sc.layer.borderColor = UIColor.lightGray.cgColor
sc.layer.masksToBounds = true
sc.frame = CGRect(origin: CGPoint(x: 10, y: 280), size: CGSize(width: 300, height: 30))
sc.addTarget(self, action: #selector(handleSegmentChange), for: .valueChanged)
return sc
}()

issue with title in navigation bar in arabic

I am having an issue with this function:
func setTitle(title:String, subtitle:String) -> UIView {
let titleLabel = UILabel(frame: CGRect(x:0, y:-5, width:0, height:0))
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.gray
titleLabel.font = UIFont.boldSystemFont(ofSize: 17)
titleLabel.text = title
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRect(x:0, y:18, width:0, height:0))
subtitleLabel.backgroundColor = UIColor.clear
subtitleLabel.textColor = UIColor.black
subtitleLabel.font = UIFont.systemFont(ofSize: 12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
let titleView = UIView(frame: CGRect(x:0, y:0, width:max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), height:30))
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width
if widthDiff > 0 {
var frame = titleLabel.frame
frame.origin.x = widthDiff / 2
titleLabel.frame = frame.integral
} else {
var frame = subtitleLabel.frame
frame.origin.x = abs(widthDiff) / 2
titleLabel.frame = frame.integral
}
return titleView
}
// Use :
self.navigationItem.titleView = setTitle("title", "subtitle")
// Source : http://stackoverflow.com/questions/12914004/uinavigationbar-titleview-with-subtitle
as shown above images, whenever someone writes in arabic[picture 2] the title will be messed up, but if someone wrote it in English[picture 1]. the label of title will remain good.
thank you in advance.
I ran code with all combinations of arabic and english words and found the problem in code. Check it out.
if widthDiff > 0 {
var frame = titleLabel.frame
frame.origin.x = widthDiff / 2
titleLabel.frame = frame.integral
} else {
var frame = subtitleLabel.frame
frame.origin.x = abs(widthDiff) / 2
titleLabel.frame = frame.integral /* subtitleLabel.frame = frame.integral */
}

how to print text from textField in label programmatically swift

i like to print textField Value in label by clicking button key. but i have been unable to do it. below is codes
import UIKit
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.gray
setupLabel()
setupTextField()
setupButton()
}
func setupLabel() {
let label = UILabel()
label.frame = CGRect(x: 40, y: 80, width: 300, height: 60)
label.text = "welcome to my world"
label.textColor = UIColor.yellow
label.font = UIFont.boldSystemFont(ofSize: 25)
label.textAlignment = .center
label.layer.borderWidth = 2
label.layer.borderColor = UIColor.yellow.cgColor
label.layer.cornerRadius = 5
view.addSubview(label)
}
func setupTextField() {
let textField = UITextField()
textField.frame = CGRect(x: 10, y: 200, width: self.view.frame.size.width - 20, height: 60)
textField.placeholder = "text here"
textField.textAlignment = .center
textField.font = UIFont.systemFont(ofSize: 25)
textField.layer.borderWidth = 2
textField.layer.borderColor = UIColor.yellow.cgColor
textField.layer.cornerRadius = 5
view.addSubview(textField)
}
func setupButton() {
let button = UIButton()
button.frame = CGRect(x: 50, y: 300, width: self.view.frame.size.width - 100, height: 60)
button.setTitle("Enter", for: .normal)
button.setTitleColor(UIColor.yellow, for: .normal)
button.layer.borderWidth = 2
button.layer.borderColor = UIColor.yellow.cgColor
button.layer.cornerRadius = 5
button.addTarget(self, action: #selector(buttonTarget), for: .touchUpInside)
view.addSubview(button)
}
func buttonTarget() {
// i missed of here
}
}
in here you need to follow two steps
you need to create the label and textfield in globally not instance, for e.g
class MainViewController: UIViewController
let label = UILabel()
let textField = UITextField()
hide the instance vale of your allocation
func setupLabel() {
//let label = UILabel()
label.frame = CGRect(x: 40, y: 80, width: 300, height: 60)
label.text = "welcome to my world"
label.textColor = UIColor.yellow
label.font = UIFont.boldSystemFont(ofSize: 25)
label.textAlignment = .center
label.layer.borderWidth = 2
label.layer.borderColor = UIColor.yellow.cgColor
label.layer.cornerRadius = 5
view.addSubview(label)
}
then you can access the value directly anywhere in your class
func buttonTarget() {
if let text = textField.text
{
label.text = text
}
}

How to add a label at bottom of imageView programmatically?

i am trying to add a label at the bottom of imageView as a subview but when image changes its height or width the label is not responsive.
So i want to make a dynamic label.
add like
var lbl1 = UILabel(frame: CGRect(x: yourimageview.frame.origin.x, y: yourimageview.frame.origin.y + yourimageview.frame.size.height + 5, width: yourimageview.frame.size.width, height: asyourWish))
lbl1.textColor = UIColor.black
lbl1.frame = position
lbl1.backgroundColor = UIColor.clear
lbl1.textColor = UIColor.white
lbl1.text = "TEST"
self.view.addSubview(lbl1)
Here example of adding label to image
let picImage:UIImageView = {
let imageView = UIImageView()
let image = UIImage(named: "test")
imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.translatesAutoresizingMaskIntoConstraints = false
return imageView
}()
let durationLabel: UILabel = {
let label = UILabel()
label.text = "1:20:12"
label.font = UIFont(name:"HelveticaNeue-Bold", size: 15.0)
label.textAlignment = NSTextAlignment.right
label.numberOfLines = 1
label.textColor = UIColor.white
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func setupView(){
// I will skip part of image setup
self.picImage.addSubview(durationLabel)
durationLabel.bottomAnchor.constraint(equalTo: picImage.bottomAnchor).isActive = true
durationLabel.leftAnchor.constraint(equalTo: picImage.leftAnchor, constant: 5).isActive = true
durationLabel.rightAnchor.constraint(equalTo: picImage.rightAnchor, constant: -5).isActive = true
}
this code will add label to image that set constraint to bottom and left and right
Try this!
var label = UILabel()
label.frame = CGRect(x: imageView.bounds.origin.x, y: imageView.bounds.origin.y, width: 300, height: 45)
label.backgroundColor = UIColor.orange
label.textAlignment = .left
label.text = "This is a test label"
self.imageView.addSubview(label)

Resources