UIDatePicker Background isn't changing - xcode

I've been trying to change the background && text color for the UIDatePicker, I'm executing this code via ViewDidLoad. The text color changes, but the background color refuses to change. Instead when I run the app and the view loads for the first time, it doesn't change the color, but if I tap inside of the textfield then go to the previous screen then click on the textfield the background color changes like it's supposed to. This is my code for the viewdidload method below:
UIDatePicker *endTimeDatePicker = [[UIDatePicker alloc]init];
endTimeDatePicker.backgroundColor = [UIColor colorWithRed:0/255
green:0/255 blue:0/255 alpha:0.8];
[endTimeDatePicker setValue:[UIColor whiteColor] forKey:#"textColor"];
[endTimeDatePicker setDate:startTime];
endTimeDatePicker.datePickerMode = UIDatePickerModeDate;
[endTimeDatePicker addTarget:self action:#selector(updateEndTime:)
forControlEvents:UIControlEventValueChanged];
[promoEndTime setInputView:endTimeDatePicker];
I'm really at a loss, I also tried other variations to set the background color...
setbackground color, set tintcolor, uicolor black
still nothing, still the same result, any assistance would be great thanks.

Normally setting backgroundColor is all that's needed. If you had added the date picker in interface builder, it would work. I suspect that when you call setInputView, your promoEndTime is overriding that setting by changing it to something else.
You might get around that by setting the background color after calling setInputView. But you might find it better to change your strategy, because date pickers are notoriously resistant to UI changes. You're already on thin ice here with Apple, because the textColor setting is undocumented. Using undocumented API is a major risk of having Apple reject your app from the store. I agree that better appearance customization would be extremely nice here, but changing the text color is asking for trouble from Apple.

In case anyone is looking for a way to change background color of calendar popup on new ios 14 uidatepicker compact style then this is what worked for me:
(UIVisualEffectView.classForCoder() as? UIAppearanceContainer.Type).map({ UIDatePicker.appearance(whenContainedInInstancesOf: [$0]).backgroundColor = UIColor.yellow })

Related

NSTextView doesn’t work when placed near the top of an NSWindow

Context
I have a window with a fullSizeContentView and a transparent titlebar and hidden titlebar.
I don’t even want the titlebar, but I had to enable it to get rounded corners on the NSWindow.
Problem
An NSTextView, when placed near the top edge, doesn’t react to any clicks. It doesn‘t let me select any text, and doesn’t let me click links I added via NSAttributedString.
This issue disappears when I disable the titlebar altogether.
Any Help would be greatly appreciated. Thanks!
Big Context
I’m trying to implement little “in-app notifications” that show peripheral status updates. I considered using NSAlert but I don’t want to prevent the user from interacting with the rest of the interface while the notifications are showing, so I decided to implement it myself.
The notifications are little, non-movable windows without a titlebar. They are basically just grey rectangles with rounded corners and a shadow that draw inside the main application window and contain one or a few lines of text. The first line of text is almost entirely behind the invisible titlebar which is why I’m having issues.
The only thing I need the notifications to do besides display text is link to webpages that contain more info about a notification’s message.
I feel like I might be approaching this wrong. If you have any suggestions or ideas on how to solve the problem, I’m eager to hear them. Thanks!
I finally figured it out!
I nailed it down to the contentInsets of the NSScrollView. (which your are for some reason forced to have around your NSTextView when creating it in Interface Builder)
The contentInsets were automatically being set to account for the invisible titlebar, even though the docs say that NSScrollView - automaticallyAdjustsContentInsets (which is set to YES by default and which I assume was causing this) doesn't do automatic insets for transparent titlebars.
After programmatically setting the scrollView's contentInsets to 0, everything works great!
In Objective C, you can set your scrollView's contentInsets to 0 like this:
NSScrollView *scrollView = (NSScrollView *)self.textView.superview.superview;
scrollView.automaticallyAdjustsContentInsets = NO; // Doesn't remove insets // Probably calling this too late
scrollView.contentInsets = NSEdgeInsetsMake(0, 0, 0, 0);
Here's a working example.
Hope this helps!

UITextField backgroundColor in UISearchBar iOS 10+

I'm trying to set the background color of the text field in my search bar to a custom color. I looked at the answer here to no avail:
Cannot change search bar background color
See how that search bar has a red text field? I followed the code and can even verify that the UISearchBarTextField object was found and the background color of it is being set to UIColor.red, but the color does not change.
I've messed around with all the background colors of the superviews with hopes that it might help but I cannot get that color to change. Maybe there's some new trick or someone can shed some light on something that may be overriding the color somehow.
extension UISearchBar {
var textField: UITextField? {
return subviews.first?.subviews.first(where: { $0.isKind(of: UITextField.self) }) as? UITextField
}
}
searchBar.textField?.backgroundColor = UIColor.red // <-- Not working
let textFieldInsideUISearchBarLabel = searchBar.textField?.value(forKey: "placeholderLabel") as? UILabel
textFieldInsideUISearchBarLabel?.textColor = UIColor.lightGray
Note that the text inside the UITextField object is changing to the lightGray like I want it, just not the UITextField background color.
After a long wait for an answer, I decided to try some experiments. I created a new project, dragged a search bar, connected it to the ViewController, added the UISearchBar extension, and set the color - exactly the same as I did in my main project.
Voila! It does set the background color as it should, and as it shows in the linked topic in the main question.
So, I put the projects side by side, opened the storyboard in each of them and started setting the properties of the searchBar, one at a time, until I could see why the bar is not being set like it should in the main project.
The very first thing I tried was, search style. My project has it set to "Minimal". I changed it to "Minimal" in the test project and noticed right away that the color was no longer set.
So, setting the "Search Style" property of the searchBar in the main project to "Default" allowed that background color to be set.
I would appreciate it greatly if anyone could comment and say why it is that I can't use "Minimal" if I want to customize the background color, or how I could make it work.

Change UIActionSheet buttons background color and button font

I have a UIActionSheet in my application. I want to change the background color of actionsheet buttons and the font of the buttons. I made a search found below code:
for (UIView *_currentView in actionSheet.subviews)
{
if ([_currentView isKindOfClass:[UIButton class]])
{
//DO YOUR WORK
}
}
but this code is not working on ios 8. for ios I found below code too:
[[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setTintColor:[UIColor redColor]];
but this code only changes the button's font color.
Is there a way for changing the button's background color too?
Basically what you are trying to do is something you should not do and should never have been doing. UIActionSheet and UIAlertController provide standard views with a very small number of variants and a completely standard appearance. You should not attempt to mess with that.
However, don't give up hope! Nothing stops you from devising your own view that looks however you want. And on iOS 8 (and iOS 7) this is very easy, because you are allowed to make a presented view controller whose view slides onto the screen and covers it only partially, just like an alert sheet. So go ahead and create your own non-standard column of buttons, rather than trying to modify Apple's standard.
What works for me is this:
UICollectionViewCell.appearance().backgroundColor = UIColor.whiteColor() // or any other color you want
Note that this affects the background when presented in a popover or on the iPhone. If you are using UICollectionViews elsewhere in your app, set the background color manually to override.

Can't disable background blur with NSPopover

I'm having no luck trying to get NSPopover back to its 10.9 appearance when running in 10.10. I have a popover which is attached to an NSView that the user drags around. The popover must be transparent so the user can still see the position of the other UI elements underneath.
All works fine under 10.9 but now under 10.10 with Apple's new gimmicky blurs, I can't seem to get back to the same appearance on 10.10 (unless like me, the user has enabled "Reduce Transparency" in System Preferences > Accessibility. A preference change I can't enforce on end users!).
Have tried:
self.draggingPopover.appearance = NSPopoverAppearanceHUD;
self.popoverView.superview.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
self.popoverView.appearance = [NSAppearance appearanceNamed:NSAppearanceNameAqua];
None of which make any difference to the popover's appearance on screen.
drawRect in my view subclass fills the background with my chosen color but ignores the alpha value and the popover is opaque.
Similarly I can use self.popoverView.layer.backgroundColor = ... but the alpha value is ignored there too!
Use:
[popover setAppearance:(NSPopoverAppearance)[NSAppearance appearanceNamed:NSAppearanceNameAqua]];
If a requirement is that the popover is transparent (regardless of any future design changes to popover), could you just set the popover window's (i.e. the popoverView's -window) alphaValue to some other value < 1.0?
You can set the Aqua appearance in the storyboard as well. Select the NSPopover's content view and use this setting:

Trouble matching the vibrant background of a Yosemite NSMenuItem containing a custom view

I am attempting to add a custom view to an NSMenuItem in the OS X 10.10 Yosemite menu bar.
The custom view is simply an NSView background with an NSTextField “label”.
The problem is that the background NSView is given Yosemite-style vibrancy/transparency when added to the menu. The NSTextfield label is not.
Through the use of NSRectFillUsingOperation I've gotten this to look good for some background colors in Yosemite. But others continue to not match. When it is working, after manually "highlighting" the view, the original colors change and no longer match. I can dig up some example code for this if needed.
Then, when it is looking somewhat good in Yosemite, it looks terrible in 10.9 Mavericks.
I've also tried setting the wantsLayer property to YES to turn the view into a CALayer-backed view. This creates other issues such as text not anti-aliasing correctly against a clear background.
My Question:
How do I display a label on top of a NSMenuItem custom view? The label's background must exactly match the view's background. Solution must work in Yosemite and Mavericks.
Example code below:
self.statusItem = [[NSStatusBar systemStatusBar]
statusItemWithLength:NSVariableStatusItemLength];
[self.statusItem setTitle:#"TEST"];
[self.statusItem setHighlightMode:YES];
[self.statusItem setEnabled:YES];
[self.statusItem setTarget:self];
NSMenu *menu = [[NSMenu alloc] init];
[menu addItemWithTitle:#"Disabled menu item" action:nil keyEquivalent:#""];
[menu addItemWithTitle:#"Enabled menu item" action:#selector(enabled) keyEquivalent:#""];
NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(30, 20, 50, 20)];
label.stringValue = #"label";
label.editable = NO;
label.bordered = NO;
label.backgroundColor = [NSColor blueColor];
//label.backgroundColor = [NSColor clearColor];
PKMenuItemView *view = [[PKMenuItemView alloc] initWithFrame:NSMakeRect(0, 0, 200, 50)];
[view addSubview:label];
NSMenuItem *viewMenuItem = [[NSMenuItem alloc] init];
[viewMenuItem setView:view];
[menu addItem:viewMenuItem];
self.statusItem.menu = menu;
I've subclassed the NSView to override drawRect: and draw a colored background:
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
[[NSColor blueColor] setFill];
NSRectFill(dirtyRect);
//NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver);
}
It is surely kinda hack, but it worked for me.
Try adding an NSImageView with empty image to your custom view. Image view must be occupy the whole view.
I think I have less "hackish" solution. It's indeed caused by the new NSVisualEffectView and Vibrancy stuff in Yosemite. I learned that there are quite complex rules how views are drawn when they're subviews of NSVisualEffectView. It was discussed on WWDC 2014 in session 220 - Adopting Advanced Features of the New UI of OS X Yosemite. I recommend you to watch this session video to get comprehensive explanation.
Shortly, it seems that your problem may be caused by colors you use. There are two new system colors - [NSColor labelColor] and [NSColor secondaryLabelColor]. These two are automatically adjusted when drawn inside NSVisualEffectView. Also, your custom view should support Vibrancy effect. This is done by overriding - (BOOL)allowsVibrancy method and returning YES.
Please check the session video mentioned above or download session slides in PDF to get precise information. This stuff is discussed from slide 124 in PDF and near the middle of the video.
Unfortunately there are currently several problems in Yosemite. As Matthes already mentioned, you can use labelColor() and secondaryLabelColor(). Using those colors do not cause the label to draw the strange background you are seeing.
However, labelColor() only works fine for VibrantDark because there the label color is white when a NSMenuItem is both highlighted and when not highlighted. With VibrantLight the labelColor is black and is therefore very difficult to read on on top of the blue highlight.
For the highlight color of the custom view of your NSMenuItem one might think that you should use selectedMenuItemColor() given its name. The problem with this is that the color doesn't actually match the menu highlight color that you see in NSMenuItems without a custom view. The color is completely wrong for both VibrantLight and VibrantDark.
Tl;dr: So how can you create a custom NSMenuItem that uses the exact same text color and highlight color? You can't. You should use labelColor() and selectedMenuItemColor() but the former only works correctly for VibrantDark, and the latter doesn't match at all.
I really hope I am wrong because I am trying to achieve the same thing :(
Edit: Here is an example project if people want to have a look.
Response from a Apple Developer Technical Support ticket I opened in 2015:
Re: DTS Auto-Ack - Vibrant background and highlighting of Custom View NSMenuItems
This is a difficult problem to tackle, especially in light of the fact that menu selection drawing was not intended for menu items with custom views, and menu selection drawing (colors, etc.) may change in the future. This is why we ask you to file bug reports so that menu selection will be honored with custom views, if asked for, so that future changes to OS X won’t require developers to continually maintain their code to match future color appearances.
The “Application Menu and Pop-up List Programming Topics” says this:
Views in Menu Items -
“A menu item with a view does not draw its title, state, font, or other standard drawing attributes, and assigns drawing responsibility entirely to the view. Keyboard equivalents and type-select continue to use the key equivalent and title as normal.”
Since all drawing is up to the developer, custom views in menu items aren’t necessarily supposed to draw “selected”.
The APIs to obtain the right selection color is obviously not doing what it’s supposed to, hence the request to file a bug report. I wish we could offer more concrete solutions to the problem but a workaround offered today may not hold up tomorrow and we don’t want to set a bad precedent on workarounds that are risky. Apple apps have access to lower level private APIs that achieve their results. We cannot offer you these solutions as they are private.
If selectedMenuItemColor() does not match the menu highlight color with Vibrant light and dark, that’s a bug to be filed and to be fixed.
Lastly, Apple recommends to use NSMenuItem’s APIs as much as possible to achieve what you want in menus. The screenshots you included can likely be done without applying custom views.
I've just discovered that +[NSColor keyboardFocusIndicatorColor] is the right color (on El Capitan at least), whereas the expected selectedMenuItemColor is by far too dark.
Per AppKit engineers at WWDC, this doesn't really work with NSMenuItem. I added that answer to this question as well.
They suggested to instead use an NSPopover to create a faux-NSMenu attached to an NSStatusItem menu bar helper.
Using code similar to the below results in vibrant background selection:
override func viewDidLoad() {
super.viewDidLoad()
let visualEffectView = NSVisualEffectView()
visualEffectView.material = .selection
// .menu or .popover for the non-selected background.
visualEffectView.state = .active
visualEffectView.blendingMode = .behindWindow
visualEffectView.isEmphasized = true
let label = NSTextField(labelWithString: "Hello, world!")
label.cell?.backgroundStyle = .emphasized
visualEffectView.addSubview(label)
visualEffectView.frame = view.bounds
label.setFrameOrigin(.zero)
view.addSubview(visualEffectView)
}
At the WWDC 2019 AppKit Lab I worked through this issue with engineers from the AppKit team.
They were surprised that it did not work by default, and encouraged me to file (more) radars:
FB6143574 - Expose private API for NSMenuItem _viewHandlesEvents
They were aware of a private API _viewHandlesEvents on NSMenuItem.
// VibrantMenuBar-Bridging-Header.h
#import <AppKit/AppKit.h>
#interface NSMenuItem ()
#property (setter=_setViewHandlesEvents:) BOOL _viewHandlesEvents;
#end
Set viewHandlesEvents to false and the background of the custom view in the NSMenuItem will be selected and appear (somewhat) as expected.
There are still issues with how labels and other subviews react to the selection. Text View text is not properly changing color.
let menuItem = NSMenuItem(title: "", action: nil, keyEquivalent: "")
menuItem.view = label
menuItem._viewHandlesEvents = false
There are some other references to _viewHandlesEvents on the internet:
How to flash a custom NSMenuItem view after selection?

Resources