I created a NSSlider programmatically and implemented it in a NSMenuItem:
let menuVolumeSliderItem = NSMenuItem()
let menuVolumeSlider = NSSlider()
menuVolumeSlider.sliderType = NSSliderType.linear
menuVolumeSlider.isEnabled = true
menuVolumeSlider.isContinuous = true
menuVolumeSlider.action = #selector(AppDelegate.doSomething)
menuVolumeSlider.minValue = 0.0
menuVolumeSlider.maxValue = 1.0
menuVolumeSlider.floatValue = 0.5
menuVolumeSlider.frame.size.width = menu.size.width
menuVolumeSlider.frame.size.height = 20.0
menuVolumeSliderItem.view = menuVolumeSlider
menu.addItem(menuVolumeSliderItem)
And essentially, it work’s like a charm:
But the result I want to achieve is a Slider with a min/max image on the left/right edge of the Slider like this one:
How can I achieve a NSMenuItem like that?
EDIT:
I’ve created a custom NSView:
let view = NSView()
view.frame.size.width = menu.size.width
view.frame.size.height = 25.0
... then created a NSImage ...
let img = NSImageView()
img.frame.size.width = 16.0
img.frame.size.height = 16.0
img.image = NSImage(named: "NSStatusAvailable")!
... and added menuVolumeSlider and img to my custom view:
view.addSubview(img)
view.addSubview(menuVolumeSlider)
menuVolumeSliderItem.view = view
menu.addItem(menuVolumeSliderItem)
... and it worked! But can anyone please give me a hint how to change the positions of the subViews?
Create a NSView that will include the slider and the two images. Then set menuVolumeSliderItem.view to be that NSView.
Related
This question already has an answer here:
images render larger when loaded programmatically on iPhone X,Xs?
(1 answer)
Closed 1 year ago.
I have an ImageView on my Storyboard layout and I put some images over this ImageView.
To maintain the proportion of the image I created a code to calculate the image scale.
static func getImageScale(_ myImage:UIImageView) -> (width: CGFloat, height: CGFloat) {
let imageViewHeight = myImage.bounds.height
let imageViewWidth = myImage.bounds.width
let imageSize = myImage.image!.size
let myScaledImageHeight = imageViewHeight / imageSize.height
let myScaledImageWidth = imageViewWidth / imageSize.width
return (width: myScaledImageWidth, height: myScaledImageHeight)
}
This is how I use the code above:
ImageMarcasHelper.addScaledImageToScreenWithoutMovement(imageStringName: nome_imagem, scaledImageWidth: percentImageScale.width, scaledImageHeigth: percentImageScale.height, view: view)
Finally, I call this:
static func addScaledImageToScreenWithoutMovement(imageStringName imageNameString:String, scaledImageWidth:CGFloat, scaledImageHeigth:CGFloat, view:UIView) {
var xFinal = 0
var scaledImageWidthMultiplied:CGFloat = 0.0
let vc: UIViewController = view.parentViewController!
let vc_name = type(of: vc)
let image = UIImage(named: imageNameString)
print(image!)
let imageView = UIImageView(image: image!)
imageView.isAccessibilityElement = true
imageView.restorationIdentifier = imageNameString
if vc_name == ResenhaMarcasCabecaController.classForCoder() ||
vc_name == ResenhaMarcasMembrosPosterioresController.classForCoder() {
print("ResenhaMarcasCabecaController view used")
xFinal = Int((image?.size.width)!/1.9)
scaledImageWidthMultiplied = (image?.size.width)! * 1
} else {
// identifica todas as outras views como ResenhaMarcasFocinhoController ou ResenhaMarcasPescocoController ou ResenhaMarcasMembrosAnterioresController
print("viewcontroller genenrica usada")
xFinal = 0
scaledImageWidthMultiplied = (image?.size.width)! * scaledImageWidth
}
imageView.frame = CGRect(
x: xFinal,
y: 0,
width: Int( scaledImageWidthMultiplied ),
height: Int( (image?.size.height)! * scaledImageHeigth )
)
view.addSubview(imageView)
}
On some iPhone models the image resize works perfectly, but on other models it is not calculated correctly.
Check below the images from an iPhone 8 and an iPhone 8 Plus
The red image on the left side is centered, but on the right side the red image is NOT centered.
How can I fix that? There is another code that can I use to fix it or do I need to adapt something on my code?
Or maybe another solution, there is any way to detect the type of screen size or dimension? The same problem happens with iPhone 11 Max and iPhone Max Pro.
The red image is centered on iPhone 11 Max, but is NOT centered on iPhone Max Pro.
--- EDIT ---
#IBOutlet weak var imagemPrincipalCabeca:UIImageView!
I have an IBOutlet that contains the ImageView that I created using Storyboard with AutoLayout and I use the image inside this ImageView to get the scale to apply to other images.
This is the code that I use to get and apply the scale from the IBOutlet that is assigned to the ImageView
let percentImageScale = ImageMarcasHelper.getImageScale(imagemPrincipalCabeca)
ImageMarcasHelper.addScaledImageToScreenWithoutMovement(
imageStringName: nome_imagem,
scaledImageWidth: percentImageScale.width,
scaledImageHeigth: percentImageScale.height,
view: view)
I find out what is the problem.
All calculations are done inside the "viewDidLoad" method. Inside this method, the calculations are not correct because the view still does't know the correct size of the subviews(the container view)
I change all the calculations to be made inside the "viewWillAppear" method. This way I was able to get the correct screen width and height for the subview.
I'm trying to display text on top of an NSImage.I use the following code
let myTextLayer = CATextLayer()
myTextLayer.string = "My text"
myTextLayer.foregroundColor = NSColor.cyan.cgColor
myTextLayer.frame = self.img_view.bounds
self.img_view.layer=myTextLayer;
This keeps producing empty NSImageView
You needs explicitly say NSImageView wantsLayer before use layers, like below
self.img_view.wantsLayer = true
let myTextLayer = CATextLayer()
myTextLayer.string = "My text"
myTextLayer.foregroundColor = NSColor.cyan.cgColor
myTextLayer.frame = self.img_view.bounds
self.img_view.layer.addSublayer(myTextLayer)
This issue came up in relation to a problem I had yesterday for which I should be able to create a workaround. As I investigated further, I found that it occurs more broadly than I originally thought. I had previously only noticed it in displayed text that included at least one newline character, but that's not the case below.
The problem seems to result from using the NSLayoutManager's boundingRect method to obtain (among other things) individual character widths and then using those widths to set characters' UITextView frame width properties. Doing so apparently causes the setting of the text view's backgroundColor to UIColor.clear to be ignored (i.e., the background becomes opaque). The Playground code below reproduces the problem, shown in red text, and shows the workaround of using a constant for widths, in black. The tighter the kerning, the more pronounced the effect.
Is this a bug? Or is it a quirk due to something else?
//: A UIKit based Playground for presenting user interface
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.bounds = CGRect(x: -100, y: -100, width: 200, height: 200)
view.backgroundColor = .white
let str = "..T.V.W.Y.."
let strStorage = NSTextStorage(string: str)
let layoutManager = NSLayoutManager()
strStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size: view.bounds.size)
textContainer.lineFragmentPadding = 0.0
layoutManager.addTextContainer(textContainer)
let strArray = Array(str)
struct CharInfo {
var char: Character
var origin: CGPoint?
var size: CGSize?
}
var charInfoArray = [CharInfo]()
for index in 0..<str.count {
charInfoArray.append(CharInfo.init(char: strArray[index], origin: nil, size: nil))
let charRange = NSMakeRange(index, 1)
let charRect = layoutManager.boundingRect(forGlyphRange: charRange, in: textContainer)
charInfoArray[index].origin = charRect.origin
charInfoArray[index].size = charRect.size
}
for charInfo in charInfoArray {
let textView0 = UITextView()
textView0.backgroundColor = UIColor.clear // Ignored in this case!!
textView0.text = String(charInfo.char)
textView0.textContainerInset = UIEdgeInsets.zero
let size0 = charInfo.size!
textView0.frame = CGRect(origin: charInfo.origin!, size: size0)
textView0.textContainer.lineFragmentPadding = CGFloat(0.0)
textView0.textColor = UIColor.red
view.addSubview(textView0)
let textView1 = UITextView()
textView1.backgroundColor = UIColor.clear // Required
textView1.text = String(charInfo.char)
textView1.textContainerInset = UIEdgeInsets.zero
var size1 = charInfo.size!
size1.width = 20 // But changing .height has no effect on opacity
textView1.frame = CGRect(origin: charInfo.origin!, size: size1)
textView1.frame = textView1.frame.offsetBy(dx: 0, dy: 20)
textView1.textContainer.lineFragmentPadding = CGFloat(0.0)
textView1.textColor = UIColor.black
view.addSubview(textView1)
}
self.view = view
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
This does seem to be a bug, but it's with NSLayoutManager's instance method boundingRect(forGlyphRange:in:). It only looks like it could be a transparency change.
According to Apple's documentation, boundingRect(forGlyphRange:in:) is supposed to "[return] a single bounding rectangle (in container coordinates) enclosing all glyphs and other marks drawn in the given text container for the given glyph range, including glyphs that draw outside their line fragment rectangles and text attributes such as underlining." But that's not what it's doing.
In this case, the width of each boundingRect gets reduced by the amount that the next glyph was shifted to the left, due to kerning. You can test this, for example, using str = "ToT" and adding print(size0.width) right after it is set. You'll get this:
6.0 // "T"; should have been 7.330078125
6.673828125 // "o"
7.330078125 // "T"
Until this bug is fixed, a workaround would be to calculate glyph size for each character in isolation.
I know it sounds easy but by default GoogleMaps default function iconView has a default alpha of 0.9. I tried changing it to 1 but it's still the same. Any suggestion? Thanks in advance.
[EDIT]
This is my code
let cView = UIView(frame: CGRectMake(0,0,400*PT,300*PT))
let innerView = UIView(frame: CGRectMake(0,0,400*PT,190*PT))
innerView.backgroundColor = UIColor.whiteColor()
innerView.layer.cornerRadius = 3
innerView.layer.masksToBounds = true
innerView.alpha = 1
cView.addSubview(innerView)
let cIcon = UIImageView(frame: CGRectMake(0*PT, 200*PT, 90*PT, 100*PT))
cIcon.image = UIImage(named: "1.png")
cView.addSubview(cIcon)
cView.backgroundColor = UIColor.clearColor()
item.iconView = cView
[EDIT]
Added screenshot of the output
[EDIT]
Final output after the answer below
Might be a bit obvious, but can you try adding this?
item.opacity = 1
I have set the following code:
let printInfo = NSPrintInfo.sharedPrintInfo
let textPrint = NSPrintOperation(view: theTextView,printInfo: printInfo())
Now I would like to set the orientation to Landscape, but I can't find any Swift functions that do this.
This is what I'm using. The NSView is called drawing.
let pinfo = NSPrintInfo.shared()
pinfo.orientation = .landscape
pinfo.bottomMargin = 0.0
pinfo.topMargin = 0.0
pinfo.leftMargin = 0.0
pinfo.rightMargin = 0.0
drawing!.print(self)
Try this:
let pmPageFormat = printInfo.PMPageFormat()
PMSetOrientation(pmPageFormat, kPMLandscape, kPMUnlocked)
printInfo.updateFromPMPageFormat()