issue with title in navigation bar in arabic - ios

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 */
}

Related

I cannot stretch the height of the titleView in the UINavigationBar

This is my code:
class UINavigationControllerCustom : UINavigationController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews();
navigationBar.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 120);
}
}
class PreferenceInput: UIViewController {
override func viewDidLoad() {
let l1 = UILabel()
l1.backgroundColor = .clear
l1.numberOfLines = 1
l1.font = UIFont.boldSystemFont(ofSize: 30.0)
l1.textAlignment = .left
l1.textColor = .black
l1.text = "Bold title"
l1.sizeToFit();
let l2 = UILabel()
l2.backgroundColor = .clear
l2.numberOfLines = 2
l2.font = UIFont.boldSystemFont(ofSize: 16.0)
l2.textAlignment = .left
l2.textColor = .darkGray;
l2.text = "This is a\nmultiline string for the navBar"
l2.sizeToFit();
let tView = UIStackView(arrangedSubviews: [l1,l2]);
tView.axis = .vertical;
let spacer = UIView()
let constraint = spacer.widthAnchor.constraint(greaterThanOrEqualToConstant: CGFloat.greatestFiniteMagnitude)
constraint.isActive = true
constraint.priority = .defaultLow
let stack = UIStackView(arrangedSubviews: [tView, spacer])
stack.axis = .horizontal
navigationItem.titleView = stack
navigationItem.titleView.sizeToFit();
}
}
And this is what I get:
I can set the height of the navigation bar but how and where should I set the constraint to stretch the height in respect of the given 120px of the custom navigation controller?
I want to provide an individual height of the navigation bar.

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 to set width of navigationTitleView and Truncate label by swift3

I have a problem about navigation titleView.
The titleView cover my right barbuttonItem and out of screen.
I need titleView just in center region and have right region for barbuttonItem.
I want to know how to set width about my title, because I can't set width successfully.
And I also want to truncating middle the label.
What's wrong with me?
Thanks.
Here is Image about my question.
Here is Image about my question.
self.navigationItem.titleView = setTitle(title: name, subtitle: "")
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.white
titleLabel.font = defaultTitleFont
titleLabel.text = title
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRect(x:5, y:18, width:0, height:0))
subtitleLabel.backgroundColor = UIColor.clear
subtitleLabel.textColor = UIColor.red
subtitleLabel.font = UIFont.systemFont(ofSize: 20)
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:35))
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
subtitleLabel.frame = frame.integral
}
return titleView
}
You have to calculate the title view size/frame beforehand.
One possible way to do this to take consideration of screen width and number of bar button items presented in the navigation bar.
Take a look at the following code (Simplified for showing only title, no subtitle):
func getTitleView (title:String, numOfButtons: Int = 0) -> UIView {
let barButtonSize = 70
let offset: CGFloat = CGFloat(numOfButtons * barButtonSize)
let frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width - offset, height: 35)
let titleView = UIView(frame:frame)
let titleLabel = UILabel(frame: titleView.bounds)
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.red
titleLabel.font = UIFont.systemFont(ofSize: 14)
titleLabel.text = title
titleLabel.numberOfLines = 1
titleLabel.textAlignment = .center
titleLabel.lineBreakMode = .byTruncatingMiddle
titleView.addSubview(titleLabel)
return titleView
}
And from viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: nil)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: nil)
self.navigationItem.titleView = getTitleView(title: "Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow Wow WowWow Wow Wow Wow Wow Wow Wow WowWow WowWowWowWowWowWowWowWow Wow Wow Wow Wow Wow Wow Wow!!", numOfButtons: 2)
}
And output:

Adding subview is not working

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)

Place Label under each point from spaceBetweenPoints

I'm using a custom UIView for creating this control with 4 hotspots with the same space between the points. I'm trying to create for labels exactly under the points and it seems like the first label is correctly aligned, but i cant seem to figure out why all of them aren't correct?
Here you see the space between each point and the radius on the points.
customSlider?.spaceBetweenPoints = 95
customSlider?.radiusPoint = 5
illustration at the moment:
customSlider?.frame = CGRectMake((self.frame.width-335)/2, 20, 335, 34)
for var i = 0;i<4;i++
{
var xPointSpace = 95
var xPos = xPointSpace * i
var xSpace = (self.frame.width-335)/2
var xWidth = Int(xSpace) + xPos
var xFloat = CGFloat(xWidth)
var textLabel:UILabel = UILabel(frame: CGRectMake(xFloat, 34, 30, 21))
textLabel.text = "lol"
textLabel.backgroundColor = UIColor.redColor()
textLabel.textAlignment = NSTextAlignment.Center
textLabel.font = UIFont(name: "HelveticaNeue", size: 12)
self.addSubview(textLabel)
}
adding the labels:
customSlider?.frame = CGRectMake((self.frame.width-335)/2, 20, 335, 34)
for var i = 0;i<4;i++
{
var xPointSpace = 95
var radiusPoint = 5
var xPos = (xPointSpace + radiusPoint * 2)* i
var xSpace = customSlider?.frame.origin.x
var xWidth = xSpace + xPos
var xFloat = CGFloat(xWidth)
var textLabel:UILabel = UILabel(frame: CGRectMake(xFloat, 34, 30, 21))
textLabel.text = "lol"
textLabel.backgroundColor = UIColor.redColor()
textLabel.textAlignment = NSTextAlignment.Center
textLabel.font = UIFont(name: "HelveticaNeue", size: 12)
self.addSubview(textLabel)
}

Resources