Changing the separator color of UINavigationBar - swift

I’m working on a iOS-App based on Xcode’s “Master-Detail Template” and want to use custom colors for some of the UI elements.
However, I couldn’t find out how to change the right separator of the UINavigationBar:
I’ve already tried to change the backgroundColor of UINavigationBar, UINavigationItem and its titleView but without success.
Would be great if someone has a clue.
EDIT:
I’ve just noted that viewed in vertical mode, it’s the whole separator that I want to ink?

A slight modification of this answer gives you
extension UINavigationBar {
func setRightBorderColor(color: UIColor, width: CGFloat) {
let rightBorderRect = CGRect(x: frame.width, y: 0, width: width, height: frame.height)
let rightBorderView = UIView(frame: rightBorderRect)
rightBorderView.backgroundColor = color
addSubview(rightBorderView)
}
}

Related

How to vertically align text of NSSecureTextField in swift for macOS [duplicate]

I have been reading through the various options on how to set the vertical alignment on an NSTextField. I want the text to be displayed in the center and to do it programatically in Swift. Here are the things I have looked so far:
http://www.cocoabuilder.com/archive/cocoa/174994-repositioning-an-nstextfieldcell.html
https://red-sweater.com/blog/148/what-a-difference-a-cell-makes
Vertically Centre Text in NSSecureTextField with subclassing
Get NSTextField contents to scale
vertically align text in a CATextLayer?
One thing I have tried in Swift is to set the following property:
textField.usesSingleLineMode = true
Any tips on the best way to vertically center text would be much appreciated!
This is very hard to do, as Apple makes this very difficult. I achieved it by subclassing NSTextFieldCell and overriding the drawingRectForBounds: method like so:
override func drawingRectForBounds(theRect: NSRect) -> NSRect {
let newRect = NSRect(x: 0, y: (theRect.size.height - 22) / 2, width: theRect.size.width, height: 22)
return super.drawingRectForBounds(newRect)
}
This is just my way to do it, I'm sure there are better ways, which I don't know (yet). And this only works for the standard font size in TextFields (which gives a text height of 22). That's why I hardcoded that. Haven't figured out yet, how to get the height in the cell if you change the font.
Result:
Try this on a playground, it centers the text perfectly, use it on your projects! Hope it helps!
import Cocoa
let cell = NSTableCellView()
cell.frame = NSRect(x: 0, y: 0, width: 100, height: 100)
let tf = NSTextField()
tf.frame = cell.frame
tf.stringValue = "MyTextfield"
tf.alignment = .Center
let stringHeight: CGFloat = tf.attributedStringValue.size().height
let frame = tf.frame
var titleRect: NSRect = tf.cell!.titleRectForBounds(frame)
titleRect.size.height = stringHeight + ( stringHeight - (tf.font!.ascender + tf.font!.descender ) )
titleRect.origin.y = frame.size.height / 2 - tf.lastBaselineOffsetFromBottom - tf.font!.xHeight / 2
tf.frame = titleRect
cell.addSubview(tf)
I have added the NSTextField inside a NSView and centered it.
Another solution was (in an iOS project) to create a UILabel and allow it adjust its size (sizeToFit()) and again embed it inside a UIView.
I personally don't like the calculations in previous answers and the second solution for iOS works for all texts size and row numbers.
I was also facing vertical alignment issue with NSTextField. My requirement involved, rendering a single-line string inside a NSTextField. Additionally,
textfield needed to be resize implying we had programatically resized the font-point-size of the text inside text-field on resize. In this scenario we faced vertical-alignment issues - the mis-alignment was tough to grasp/understand in a straight forward way.
What finally worked:
So, in my scenario a simple,
turn off the "Single Line Mode" in interface builder
for the text-field solved the issue.
The accepted answer works perfectly and here's the Swift3 version.
class VerticallyAlignedTextFieldCell: NSTextFieldCell {
override func drawingRect(forBounds rect: NSRect) -> NSRect {
let newRect = NSRect(x: 0, y: (rect.size.height - 22) / 2, width: rect.size.width, height: 22)
return super.drawingRect(forBounds: newRect)
}
}

insertSubview() covers the whole Mainview even though inserted at 0

I insert a UIView into a UIButton with following code:
let backgroundView = UIView()
backgroundView.backgroundColor = .red
backgroundView.translatesAutoresizingMaskIntoConstraints = false
blueButton.insertSubview(backgroundView, at: 0)
NSLayoutConstraint.activate([
backgroundView.leadingAnchor.constraint(equalTo: blueButton.leadingAnchor),
backgroundView.trailingAnchor.constraint(equalTo: blueButton.trailingAnchor),
backgroundView.topAnchor.constraint(equalTo: blueButton.topAnchor),
backgroundView.bottomAnchor.constraint(equalTo: blueButton.bottomAnchor)
])
The promlem is that the backgroundView covers the whole button and I only see the red field instead of the button (its an image) with a red background (my subView).
This is the storyboard part of my image. I don´t do something else in the code with this buttons with the exception of trying to put a subView into:
My goal is to have a circle background like in the picture below. For example the red circle button has a rounded red (but brighter than the buttons red) backgroundView.The standard background of the button should stay the same.
I also tried to send the subView into the background but it didn´t work for me:
blueButton.sendSubviewToBack(backgroundView)
I reduced the alpha value of the subview to see if the button image is still there.
for view in blueButton.subviews {
view.alpha = 0.5
}
And it is:
How can I solve this problem?
Do not inject extra subviews into a button. If the goal is to make the background color of the button red, set its backgroundColor to .red. If the goal is to put something behind the button image, that is what the backgroundImage is for. Or just make the button image look like the image you really want.
I made this button:
It looks a lot like your picture. Here's the code:
let im = UIGraphicsImageRenderer(size: CGSize(width: 30, height: 30)).image {
ctx in
UIColor.red.withAlphaComponent(0.2).setFill()
ctx.cgContext.fillEllipse(in: CGRect(x: 0, y: 0, width: 30, height: 30))
UIColor.red.setFill()
ctx.cgContext.fillEllipse(in: CGRect(x: 5, y: 5, width: 20, height: 20))
}
b.setImage(im.withRenderingMode(.alwaysOriginal), for: .normal)
I think that's a lot better than messing with unwanted illegal subviews.

Button with multiple accessible labels and images in Swift

I need to create custom button class, reuse it 4 times and I also need to override its text and image name. My next problem is how to set its frame somehow dynamically (now it is static), because I need this 4 buttons in grid 2x2.
I'm trying to create button exactly like this: https://imgur.com/a/dNhUGhc.
I have coded this but it is static and in ViewController I can't edit (override) these labels and image name. And if I tried to reuse this class I would have them in the same spot, because frame settings is exactly the same.
I'm subclassing UIButton. If something more suitable exists just let me know.
Code for adding label
// city label
let cityRect = CGRect(x: 0, y: 20, width: buttonWidth, height: 25)
let cityLabel = UILabel(frame: cityRect)
cityLabel.text = "Label"
cityLabel.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
cityLabel.textAlignment = .center
addSubview(cityLabel)
Code for adding image
// image
let imageView = UIImageView(image: UIImage(named: "something"))
imageView.frame = CGRect(x: 0, y: 60, width: 40, height: 40)
imageView.center.x = self.center.x - 20
addSubview(imageView)
Can you guys help me? Thanks
It looks like what you need to do is use an IBOutlet. Basically, an IBOutlet will give you a reference within your code (custom UIView or UIViewController subclass) to the button that you've setup in xib or storyboard. Then you can make any changes or adjustments that you want to it at runtime.
Check this out to learn more about IBOutlets and how to set them up in your project.

Colored text background with rounded corners

I'm currently working on an iOS application in Swift, and I need to achieve the text effect shown in the attached picture.
I have a label which displays some text wrote by the user, and I need to make the text background corners (not the label background) rounded.
Is there a way to do that?
I'd search the web and Stackoverflow but with no luck.
Thank you.
Here is some code that could help you. The result I got is quite similar to what you want.
class MyTextView: UITextView {
let textViewPadding: CGFloat = 7.0
override func draw(_ rect: CGRect) {
self.layoutManager.enumerateLineFragments(forGlyphRange: NSMakeRange(0, self.text.count)) { (rect, usedRect, textContainer, glyphRange, Bool) in
let rect = CGRect(x: usedRect.origin.x, y: usedRect.origin.y + self.textViewPadding, width: usedRect.size.width, height: usedRect.size.height*1.2)
let rectanglePath = UIBezierPath(roundedRect: rect, cornerRadius: 3)
UIColor.red.setFill()
rectanglePath.fill()
}
}
}
Xavier solution works great.
If you want update background in real-time, use: textView.setNeedsDisplay()

Vertically aligning text in an NSTextField using Swift

I have been reading through the various options on how to set the vertical alignment on an NSTextField. I want the text to be displayed in the center and to do it programatically in Swift. Here are the things I have looked so far:
http://www.cocoabuilder.com/archive/cocoa/174994-repositioning-an-nstextfieldcell.html
https://red-sweater.com/blog/148/what-a-difference-a-cell-makes
Vertically Centre Text in NSSecureTextField with subclassing
Get NSTextField contents to scale
vertically align text in a CATextLayer?
One thing I have tried in Swift is to set the following property:
textField.usesSingleLineMode = true
Any tips on the best way to vertically center text would be much appreciated!
This is very hard to do, as Apple makes this very difficult. I achieved it by subclassing NSTextFieldCell and overriding the drawingRectForBounds: method like so:
override func drawingRectForBounds(theRect: NSRect) -> NSRect {
let newRect = NSRect(x: 0, y: (theRect.size.height - 22) / 2, width: theRect.size.width, height: 22)
return super.drawingRectForBounds(newRect)
}
This is just my way to do it, I'm sure there are better ways, which I don't know (yet). And this only works for the standard font size in TextFields (which gives a text height of 22). That's why I hardcoded that. Haven't figured out yet, how to get the height in the cell if you change the font.
Result:
Try this on a playground, it centers the text perfectly, use it on your projects! Hope it helps!
import Cocoa
let cell = NSTableCellView()
cell.frame = NSRect(x: 0, y: 0, width: 100, height: 100)
let tf = NSTextField()
tf.frame = cell.frame
tf.stringValue = "MyTextfield"
tf.alignment = .Center
let stringHeight: CGFloat = tf.attributedStringValue.size().height
let frame = tf.frame
var titleRect: NSRect = tf.cell!.titleRectForBounds(frame)
titleRect.size.height = stringHeight + ( stringHeight - (tf.font!.ascender + tf.font!.descender ) )
titleRect.origin.y = frame.size.height / 2 - tf.lastBaselineOffsetFromBottom - tf.font!.xHeight / 2
tf.frame = titleRect
cell.addSubview(tf)
I have added the NSTextField inside a NSView and centered it.
Another solution was (in an iOS project) to create a UILabel and allow it adjust its size (sizeToFit()) and again embed it inside a UIView.
I personally don't like the calculations in previous answers and the second solution for iOS works for all texts size and row numbers.
I was also facing vertical alignment issue with NSTextField. My requirement involved, rendering a single-line string inside a NSTextField. Additionally,
textfield needed to be resize implying we had programatically resized the font-point-size of the text inside text-field on resize. In this scenario we faced vertical-alignment issues - the mis-alignment was tough to grasp/understand in a straight forward way.
What finally worked:
So, in my scenario a simple,
turn off the "Single Line Mode" in interface builder
for the text-field solved the issue.
The accepted answer works perfectly and here's the Swift3 version.
class VerticallyAlignedTextFieldCell: NSTextFieldCell {
override func drawingRect(forBounds rect: NSRect) -> NSRect {
let newRect = NSRect(x: 0, y: (rect.size.height - 22) / 2, width: rect.size.width, height: 22)
return super.drawingRect(forBounds: newRect)
}
}