How can I create a label text with shadow? - xcode

I'm trying to create a label text with a shadow created automatically by the system. In iOS I know that you can use an Attributed style for the label, but in OS X I can't find this option. Could you help?

You can do that with Core Animation (a.k.a. CALayer). Views in iOS are layer-backed by default, but NSView on Mac OS X are much older and requires you to turn on layer manually.
The easiest way is to go to the View Effects Inspector (Cmd + Alt + 8):
If you want to add the shadow programmatically:
override func awakeFromNib() {
let shadow = NSShadow()
shadow.shadowOffset = NSMakeSize(5,5)
shadow.shadowBlurRadius = 5
shadow.shadowColor = NSColor.blackColor()
myLabel.superview?.wantsLayer = true
myLabel.shadow = shadow
}

Related

NSAppearance is not updating when toggling dark mode

I have a macOS app that runs only in the macOS status bar. I changed the "Application is agent (UIElement)" property in the Info.plist to "YES":
<key>LSUIElement</key>
<true/>
I have a timer that prints out the appearance's name every 5 seconds like this:
Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in
let appearance = NSAppearance.currentDrawing()
print(appearance.name)
}
Problem
The name doesn't actually change when I toggle dark/light mode in system settings. It always prints the name of the appearance that was set when the application launched.
Is there a way to listen to system appearance changes?
Goal
My end goal is actually to draw an NSAttributedString to an NSImage, and use that NSImage as the NSStatusItem button's image.
let image: NSImage = // generate image
statusItem.button?.image = image
For the text in the attributed string I use UIColor.labelColor that is supposed to be based on the system appearance. However it seems to not respect the system appearance change.
When I start the application in Dark Mode and then switch to Light Mode:
When I start the application in Light Mode and then switch to Dark Mode:
Side note
The reason why I turn the NSAttributedString into an NSImage and don't use the NSAttributedString directly on the NSStatusItem button's attributedTitle is because it doesn't position correctly in the status bar.
The problem with drawing a NSAttributedString is, that NSAttributedString doesn't know how to render dynamic colors such as NSColor.labelColor. Thus, it doesn't react on appearance changes. You have to use a UI element.
Solution
I solved this problem by passing the NSAttributedString to a NSTextField and draw that into an NSImage. Works perfectly fine.
func updateStatusItemImage() {
// Use UI element: `NSTextField`
let attributedString: NSAttributedString = ...
let textField = NSTextField(labelWithAttributedString: attributedString)
textField.sizeToFit()
// Draw the `NSTextField` into an `NSImage`
let size = textField.frame.size
let image = NSImage(size: size)
image.lockFocus()
textField.draw(textField.bounds)
image.unlockFocus()
// Assign the drawn image to the button of the `NSStatusItem`
statusItem.button?.image = image
}
React on NSAppearance changes
In addition, since NSImage doesn't know about NSAppearance either I need to trigger a redraw on appearance changes by observing the effectiveAppearance property of the button of the NSStatusItem:
observation = statusItem.observe(\.button?.effectiveAppearance, options: []) { [weak self] _, _ in
// Redraw
self?.updateStatusItemImage()
}

Change font size in Xamarin.IOS and Xamarin.Android Cursor Modifier?

I have charts with 15-17 lines and the cursor modifier cuts off the view at 6 on phones. It looks great on tablets, but on phones, as said, only shows six. Is there a way to decrease the text size in the modifier to fit more lines?
As for Android I would suggest to take a look on Custom Cursors example and use it as a base. In this example CustomXySeriesTooltip inherits from TextView which is used to render tooltip's text. So you can set font size for it like on regular TextView ( in ctor or internalUpdate override ):
public CustomXySeriesTooltip(Context context, XySeriesInfo seriesInfo) {
super(context, seriesInfo);
this.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
}
And the code for Xamarin.Android should be similar to Java one.
As for iOS - you can use dataStyle property provided by SCICursorModifierStyle which allows to specify font size:
SCITextFormattingStyle * textFormatting = [SCITextFormattingStyle new];
textFormatting.fontSize = 16;
textFormatting.fontName = #"Helvetica";
cursor.style.dataStyle = textFormatting;
Or you can create custom modifier like in this example.

Swift - cycling through background images

I'm completely new to coding and I'm trying to learn Swift. I'm trying to cycle through background images for an app. The images I have are named 1.jpg, 2.jpg, 3.jpg, 4.jpg. When I try run the simulator, the "super.viewDidLoad()" line is highlighted green with the comment, "Thread 1, Breakpoint 3.1." Here's my code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var imageList = [UIImage]()
for i in 1...4 {
let imageName = "\(i).jpg"
var image = UIImage(named:imageName)
imageList.append(image)
}
self.myImageView.animationImages = imageList
self.myImageView.animationDuration = 4.0
self.myImageView.startAnimating()
It sounds like you've set a breakpoint there. If there's a blue pointer to the left of the line, click it to disable it. Or, use the keyboard shortcut command-Y to disable all breakpoints.

How do you create a new NSWindow using Swift in XCode and add content to it programatically?

I come from a background in Java, and I'm trying out using swift for creating OSX and iOS applications. My current project is essentially a flashcard application, and it needs to be able to create a popup window for text-based user prompts (ie, to ask what the question is for the card, or to add String tags for sorting the flashcards by type). Here is the code that I put together so far:
//Pulls up a prompt box to add tags
#IBAction func AddTagButton(sender: AnyObject) {
//Declare new subwindow
var win = NSWindow(contentRect: NSMakeRect(100, 100, 400, 150),
styleMask: 1 | 2 | 4 | 8,
backing: NSBackingStoreType.Buffered, defer: true);
win.title = "Tag Adder";
win.center();
//Add the window to the main viewer
window.addChildWindow(win, ordered:NSWindowOrderingMode.Above);
var controller = NSWindowController(window: win);
controller.showWindow(self);
}
This pulls up a new window with the ability to close, resize, minimize, and so on. I need to add a WrappedTextField to this window programmatically, but I couldn't find any resources on how to do so. In Java, the closest analogy would be something along the lines of
JFrame frame = new Jframe();
JLabel label = new JLabel("Sample text");
frame.add(label); //How is this done in Swift?
frame.setVisible(true);
I wrote the main NSWindow by modifying the .xib in XCode (Xcode 6, Beta version 6), but I can't figure out for the life of me how to use the WYSIWYG editor to make a window appear at the push of a button. The best I could do was to make another NSWindow that was minimized/hidden by default, but would show itself when you pushed the button (which isn't exactly a very good solution). The other feature I found was an NSAlert, but that doesn't have a text field for users to input data. My question is how do you add content to an NSWindow that pops up at the push of a button, either by modifying the above method, or by using the .xib GUI editor that XCode provides?
You should add content to the contentView of NSWindow.
let textField =. NSTextView()
textView.stringvalue = "Some string"
textView.frame = CGRectMake(10,20,50,400)
mywindow.contentView.addSubview(textView)

Is that possible to have a sliding panel?

I am developing an application in wp7, the application is already been developed in android and iPhone.
Both uses a component sliding panel as they are default in it, now for the same appearance am supposed to use the component gives the same look and feel.
Is that possible to use any combination of components OR any customized dll available for that component OR is there any alternated equivalent component available for this sliding pannel.
The sliding panel i expect is like this Video
My idea is very simple, just use popup with custom animation.
DoubleAnimation anima = new DoubleAnimation();
anima.From = //current position;
anima.To = //slider position;
//animation now proportional to pixel difference
anima.Duration = new Duration(System.TimeSpan.FromMilliseconds(Math.Abs((300))));
//Debug.WriteLine("Duration=" + TimeSpan.FromMilliseconds(Math.Abs((to - from) * 2)));
// Set attached properties
Storyboard.SetTarget(anima, m_Popup);
//Storyboard.SetTargetProperty(anima, new PropertyPath(System.Windows.Controls.Primitives.Popup.WidthProperty));
Storyboard.SetTargetProperty(anima, new PropertyPath(System.Windows.Controls.Primitives.Popup.VerticalOffsetProperty));
// Create storyboard, add animation, and fire it up!
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(anima);
storyboard.Begin();

Resources