Text Direction of NSTextField - swift

I want a NSTextField with text direction as
how could I achieve this? thanks in advance for any help.

Choose orientation to VerticalĀ and then set text.
The input must be look like that.
I missed the NSTextFieldpoints so did it with NSTextView thanks to comment of #Willeke.
Cocoa framework has some points to rotate UI components.
For your NSTextField
myTextField.rotate(byDegrees: 90)
set your width & height carefully.

I rotate the NSTextField
nameTF.rotate(byDegrees: 270)
calculate the new height and width of NSTextField
let newHeight = nameTF.bestHeight(for: nameTF.stringValue, width: nameTF.frame.width)
let newWidth = nameTF.bestWidth(for: nameTF.stringValue, height: nameTF.frame.height)
set the new frame of NSTextField
nameTF.frame = CGRect(x: nameTF.frame.origin.x, y: self.view.frame.height - newWidth - 30, width: newHeight, height: newWidth)
used the extension of NSTextField
extension NSTextField {
func bestHeight(for text: String, width: CGFloat) -> CGFloat {
stringValue = text
let height = cell!.cellSize(forBounds: NSRect(x: 0, y: 0, width: width, height: .greatestFiniteMagnitude)).height
return height
}
func bestWidth(for text: String, height: CGFloat) -> CGFloat {
stringValue = text
let width = cell!.cellSize(forBounds: NSRect(x: 0, y: 0, width: .greatestFiniteMagnitude, height: height)).width
return width
}
}

Related

Programmatically drawing custom oval shape on screen swift

How can i draw custom oval shape like in below image in swift (not swiftUI).
Thank you in advance
I have tried to clone similar view using UIView and was able to create similar UI as you have stated on screenshot
And here is my code snippet
let width: CGFloat = view.frame.size.width
let height: CGFloat = view.frame.size.height
let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height), cornerRadius: 0)
let rect = CGRect(x: width / 2 - 150, y: height / 2.5 - 100, width: 300, height: 400)
let circlePath = UIBezierPath(ovalIn: rect)
path.append(circlePath)
path.usesEvenOddFillRule = true
let fillLayer = CAShapeLayer()
fillLayer.path = path.cgPath
fillLayer.fillRule = .evenOdd
fillLayer.fillColor = UIColor.red.cgColor
fillLayer.opacity = 0.5
view.layer.addSublayer(fillLayer)
Hope this helps you. Good day.
You can draw oval path like this
class CustomOval: UView {
override func drawRect(rect: CGRect) {
var ovalPath = UIBezierPath(ovalIn: rect)
UIColor.gray.setFill()
ovalPath.fill()
}
}

How can I show the rest of a character that has gone slightly outside of UITextView?

I have a UITextView which changes size depending on the text the user inputs (the purple box), which is inside another UIView (the red box).
But when using a handwritten style font like this, the end character sometimes gets cut off at the edge:
I have tried used text1.clipsToBounds = false but that didn't show the edge of the character. Is there a way to show the full character without changing the width of the text view?
Also here is the code I am using to set up the text view:
let text1 = UITextView()
text1.text = ""
text1.font = UIFont(name: "Gotcha", size: 27)
text1.frame = CGRect(x: 10, y: 5, width: 70, height: 50)
text1.isScrollEnabled = false
text1.delegate = self
text1.textAlignment = .center
text1.isEditable = false
text1.isSelectable = false
holdingView.addSubview(text1)
The frame then gets updated with this function, and whenever the text is changed:
func adjustTextViewSize(_ textView: UITextView) {
let maxWidth = 300
let newSize = textView.sizeThatFits(CGSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame = CGRect(x: (textView.frame.minX), y: (textView.frame.minY), width: newSize.width, height: newSize.height)
}
Thanks!
Update:
I solved this by adding an extra 30px to newSize.width for any font that is handwritten:
if fontFile?.isHandwritten == true {
currentView.widthConstraint?.constant = newSize.width + 30
currentTextHoldingView.widthConstraint?.constant = newSize.width + 30
}
call this function for get height according to string length
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin,
attributes: [NSAttributedString.Key.font: font], context: nil)
return ceil(boundingBox.height)
}
}

How to change window frame size without change its location

self.view.window?.frame.size.width = 430
self.view.window?.frame.size.height = 310
The height and width are read-only, so seems the only way to change the dimension of a frame is to re-assign an NSRect to it using code below,
self.view.window?.setFrame(NSMakeRect(0, 0, 430, 310), display: true, animate: true)
Is there a way to change window frame size without change its location?
You can use the origin of the original frame and make a new NSRect with a different size.
Something like this for instance:
func resizeFrame(newWidth: CGFloat, newHeight: CGFloat) {
if let originalFrame = view.window?.frame {
let newSize = CGSize(width: newWidth, height: newHeight)
view.window?.setFrame(NSRect(origin: originalFrame.origin, size: newSize), display: true, animate: true)
}
}
Used like this:
resizeFrame(newWidth: 430, newHeight: 310)
Hope that helps.
As Gerd K said, the y coordinate needs to be adjusted. To save others time, here is that calculation fashioned after pbodsk's example:
func resizeFrame(newWidth: CGFloat, newHeight: CGFloat) {
if let originalFrame = view.window?.frame {
let newY = originalFrame.origin.y + originalFrame.size.height - newHeight
view.window?.setFrame(NSRect(x: originalFrame.origin.x, y: newY, width: newWidth, height: newHeight), display: true, animate: true)
}
}
Usage:
resizeFrame(newWidth: 430, newHeight: 310)

Navigationbar height increase and decrease in ios

i am new to swift and here i have a requirement i want to increase/ decrease navigation bar height as per requirement
Here: To increase navigationbar height i used this lines
extension UINavigationBar {
override open func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.size.width, height: 99.0)
}
}
this lines are working .but how to decrease navigationbar height
Thank you in advance
You can use this sample project.
https://developer.apple.com/library/content/samplecode/NavBar/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007418
Why don't you just simply set the frame for your navigationBar?
let size = CGSize(width: UIScreen.main.bounds.size.width, height: 100)
navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)

What is the difference between NSRectFill and NSBezierPath(rect).fill

I know I can fill a rect using NSRectFill(bounds). However I wanted to preserve transparency for PDF output and I discovered that I can do that only with NSBezierPath(rect: bounds).fill()
What is the difference (behind the scenes) of those two?
func drawBackground() {
CGContextSaveGState(currentContext)
if (NSGraphicsContext.currentContextDrawingToScreen()) {
NSColor(patternImage: checkerboardImage).set()
NSRectFillUsingOperation(bounds, NSCompositingOperation.CompositeSourceOver)
}
NSColor.clearColor().setFill()
//NSRectFill(bounds) //option 1
NSBezierPath(rect: bounds).fill() // option 2
CGContextRestoreGState(currentContext)
}
extension NSImage {
static func checkerboardImageWithSize(size : CGFloat) -> NSImage {
let fullRect = NSRect(x: 0, y: 0, width: size, height: size)
let halfSize : CGFloat = size * 0.5;
let upperSquareRect = NSRect(x: 0, y: 0, width: halfSize, height: halfSize);
let bottomSquareRect = NSRect(x: halfSize, y: halfSize, width:halfSize, height: halfSize);
let image = NSImage(size: NSSize(width: size, height: size))
image.lockFocus()
NSColor.whiteColor()
NSRectFill(fullRect)
NSColor(deviceWhite: 0.0, alpha:0.1).set()
NSRectFill(upperSquareRect)
NSRectFill(bottomSquareRect)
image.unlockFocus()
return image
}
}
I'm mostly an iOS programmer and not very fluent these days over on the AppKit side of things, but my guess is that you're getting the wrong NSCompositingOperation. I see from the docs that NSRectFill uses NSCompositeCopy. Perhaps it would work better if you used NSRectFillUsingOperation, where you get to specify the compositing operation.