Customize background and text color in UIDatePicker in iOS 12 - uikit

In previous iOS versions, I was able to change the text and background colors using the something like the following:
let datePicker = UIDatePicker()
datePicker.datePickerMode = UIDatePickerMode.date
datePicker.setValue(UIColor.white, forKey: "textColor")
datePicker.backgroundColor = UIColor.black.withAlphaComponent(0.6)
This is no longer working in Xcode 10/iOS 12. The date picker is displayed with its default colors. Has anyone found a solution for customizing the text and background colors in iOS 12?

It seems something is resetting those values between when I set them and when the view is displayed. I was able to solve this by subclassing UIDatePicker and setting the values in layoutSubviews(). There may be a more performant place to set the colors, but this is working for me for now.
class DatePicker: UIDatePicker {
override func layoutSubviews() {
super.layoutSubviews()
backgroundColor = UIColor.black.withAlphaComponent(0.6)
setValue(false, forKey: "highlightsToday")
setValue(UIColor.white, forKey: "textColor")
}
}

Related

Accessing system colors in WatchKit

I am trying to use UIKit colors for my Apple Watch interface. You can do it in iOS with UIColor class properties like .systemBackground and others. For example:
let myColor = UIColor.systemBlue
Gives me error when compiling watchOS extension target:
Type 'UIColor' has no member 'UIColor.systemBlue'.
I wonder tis there alternative way to get this system colors, and if not — what I need is to get a color of some UI elements, like SwiftUI table view row background which looks very similar to UIColor.systemGray5.
#State private var isActive = false
var body: some View {
List {
Section() {
ForEach(self.dataSource) { item in
CustomCell()
.listRowPlatterColor(self.isActive ? Color(UIColor.systemGray5) : Color(.orange))
}
}
}
}
Code above won't compile because UIColor.systemGray5 is not found in WatchKit. I have tried to create a class which is sued both in iPhone and Watch target and it fixes Xcode autocompletion. But the app breaks when trying to use it the Apple Watch target.
I hope there's a way rather then finding correct color and hard-coding it.
Looking at the documentation, the UIColor.system-ish are only available for iOS, Catalyst and some for tvOS. What you can do is extend UIColor and create you systemGray5:
extension UIColor {
static var mySystemGray5: UIColor {
return .init(red: 229/255, green: 229/255, blue: 234/255, alpha: 1)
}
}
And use on your code like:
ForEach(self.dataSource) { item in
CustomCell()
.listRowPlatterColor(self.isActive ? Color(UIColor.mySystemGray5) : Color(.orange))
}
Since you are using SwiftUI, Color.blue is equivalent to UIColor.systemBlue.
Unfortunately, Color doesn't have a lots of UIColor system colors, hopefully Apple add missing colors on WWDC 2020.
May be use can use something like Color.gray.opacity.opacity(0.25) in the meanwhile?

Set UIBarButtonItem gray color when disabled

I have an extension for UIColor to get color from hex string. I'm using it as per below:
self.navigationItem.rightBarButtonItem?.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor(hexString: "#C0BFC0")], for: UIControlState.disabled)
self.navigationItem.rightBarButtonItem?.isEnabled = false
For some strange reason the color of the rightBarButtonItem is the same as before. Is there a way to change it when disabled? I have the above in my viewDidLoad function
I tried reading the below:
UIBarButtonItem is disabled, but has normal color
Change color of disabled bar button item in iOS
I'm able to change the color when it is not disabled. Seems when its disabled the colors are not obeyed?
when its disabled the colors are not obeyed?
I hit this bug with some toolbar items. My workaround is to ensure that the UIBarButtonItem title changes at runtime, when the disabled color should change. To do this, change the disabled color, then force the title to change by adding an invisble Unicode space if needed.
For example in Swift:
let zeroWidthSpaceStr = "\u{200B}"
func forceChangeItemTitle(_ item:UIBarButtonItem, newTitle:String) {
// Ensure the button item title is changed. Needed to pick up change in disabled text color
var newTitle = newTitle
if item.title == newTitle {
// Title already set, so change it invisibly
newTitle += zeroWidthSpaceStr
}
item.title = newTitle
}

How to change the action of NSColorWell?

I can use NSColorWell as button to change the color of selected text. Since NSColorWell is object of an NSControl it has target and action. I guess, the action is implementing the code to change the color of the selected text in NSTextView. Where can I find this code for NSColorWell action? I would like to change it in away that I can use NSColorWell to change the background of the selected text, and ultimately to have in ToolBar two NSColorWell buttons: one to change text's foreground color and second one for text's background color.
NSColorWell is just a rectangular control to change a color.
You can either create an IBAction and connect it to the action of the color well in the Connections Inspector (⌥⌘6) of Interface Builder
#IBAction func changeColor(_ sender : NSColorWell)
{
let color = sender.color
// do something with the color
}
Or bind the value in Bindings Inspector (⌥⌘7) of Interface Builder to a dynamic property, this example will set the color well to a default value of green.
dynamic var color : NSColor = .green {
didSet {
// do something with the color
}
}

Changing tintcolor for a specific TabBarItem in Swift

I have 3 TabBarItems in my ViewController
One of them is default when screen loaded. But it is not highlighted
I am trying to highlight it manually
verride func viewDidLoad() {
super.viewDidLoad()
if let items = self.TabBar.items as? [UITabBarItem]? {
let button = items![1]
button.image = button.image?.tabBarImageWithCustomTint(UIColor.redColor())
}
I am getting an error that "Value of type UIImage has no member tabBarImageWithCustomTint"
Any suggestions?
There are two options to set mode for images. Here i am explaining using ImageAssets
Step 1: Add image to ImageAssets.
Step 2: Set the Render As to Template Image from attribute inspector
See screenshot:
And keep the same code which you have done already.
I believe you have to do:
button.image?.tabBarImageWithCustomTint = UIColor.redColor()

Transparent background WKWebView (NSView)

I am building a Mac application using Swift. Therefor, I want to make a WKWebView transparent, so it shows the text of the loaded HTML, but the background of my underlaying NSWindow is visible.
I tried
webView.layer?.backgroundColor = NSColor.clearColor().CGColor;
which hadn't any effect. WKWebView inherits from NSView, but I don't know if this helps.
Another solution would be to insert a NSVisualEffectView as the background of the WebView, but I don't know how to accomplish that, either!
Use this in macOS 10.12 and higher:
webView.setValue(false, forKey: "drawsBackground")
It was not supported, then they fixed it:
https://bugs.webkit.org/show_bug.cgi?id=134779
The way to make it transparent is to:
myWebView.opaque = false
Code below works for me perfectly, also color is set to clearColor by default.
[wkWebView setValue:YES forKey:#"drawsTransparentBackground"];
I used this for macOS 10.12. without problems in OjbC:
[self.webView setValue:#YES forKey:#"drawsTransparentBackground"];
Under macOS 10.13.+ I got the following console warning message:
-[WKWebView _setDrawsTransparentBackground:] is deprecated and should not be used
The ONLY working solution was:
[self.webView setValue:#(NO) forKey:#"drawsBackground"];
I tried the below in many scenarios and it didn't work:
give the webView and the enclosingScrollView a layer and edit it's properties (backgroundColor, isOpaque)
give the webView and the enclosingScrollView a clear background color
inject javascript without the setValue forKey: in the webview.
Additionally I did use:
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation
{
if (self.isWebviewsBackgroundTransparent) {
[self insertTransparentBackgroundTo:webView];
}
}
- (void)insertTransparentBackgroundTo:(WKWebView *)webView
{
NSString *transparentBackgroundJSSString = #"document.body.style = document.body.style.cssText + \";background: transparent !important;\";";
[webView evaluateJavaScript:transparentBackgroundJSSString completionHandler:nil];
}
Updated, slightly better solution (2022). There is a private property drawsBackground on WKWebViewConfiguration. This property has been introduced in macOS 10.14 so it won't go away.
//https://opensource.apple.com/source/WebKit2/WebKit2-7610.2.11.51.8/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h.auto.html
//One can verify that the property still exists:
//https://github.com/WebKit/WebKit/blob/main/Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfigurationPrivate.h
#property (nonatomic, setter=_setDrawsBackground:) BOOL _drawsBackground WK_API_AVAILABLE(macos(10.14), ios(12.0));
Example:
let configuration = WKWebViewConfiguration()
var requiresDrawBackgroundFallback = false
if #available(OSX 10.14, *) {
configuration.setValue(false, forKey: "sward".reversed() + "background".capitalized) //drawsBackground KVC hack; works but private
} else {
requiresDrawBackgroundFallback = true
}
let webView = WKWebView(frame: .zero, configuration: configuration)
if requiresDrawBackgroundFallback {
webView.setValue(false, forKey: "sward".reversed() + "background".capitalized) //drawsBackground KVC hack; works but private
}

Resources