Reputation: 1195
I'm currently in the process of porting my iOS app to macOS using Project Catalyst.
All of my text fields, text views and table views have a blue outline when active.
I've noticed it in Apple Catalyst apps (e.g. News) in recent betas so I'm hoping it's just a bug.
Has anyone found any way to remove it otherwise?
Upvotes: 13
Views: 3412
Reputation: 319
This solution is no longer working.
I found an alternative that does not require using private APIs. You just need to set focusEffect = nil.
Example:
extension UIView {
func preventSetFocusRingForMac() {
#if targetEnvironment(macCatalyst)
focusEffect = nil
#endif
}
}
Upvotes: 0
Reputation: 2279
The solution proposed here hasn't worked for me in situations where pressing tab adds a blue rectangle around entire views. I've seen it happen for the whole page of a UIPageViewController, for the cells of a UITableView and more. The only solution I was able to use to fix this is to override the key press.
#if targetEnvironment(macCatalyst)
open override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
guard let key = presses.first?.key else { return }
switch key.keyCode {
case .keyboardTab: break
default: super.pressesBegan(presses, with: event)
}
}
#endif
Upvotes: 0
Reputation: 313
Please don't do this - this is a focus indicator for accessibility and is important for keyboard-only users.
Upvotes: 1
Reputation: 1275
This can also be done without any code in Interface Builder for specific buttons, if that fits your needs.
In the identity inspector, just set the user-defined run-time attribute to 1 like so:
Upvotes: 3
Reputation: 131
It helps to disable focus ring in all "view" classes in Catalyst
extension UIView {
#if targetEnvironment(macCatalyst)
@objc(_focusRingType)
var focusRingType: UInt {
return 1 //NSFocusRingTypeNone
}
#endif
}
Upvotes: 13
Reputation: 173
A slight improvement to Amerino's answer for greater flexibility and use in Storyboards:
@IBDesignable
class UITextViewCS: UITextView {
@IBInspectable
public var focusRing: UInt = 1 // 0-default, 1-None, 2-Exterior
#if targetEnvironment(macCatalyst)
@objc(_focusRingType)
var focusRingType: UInt {
guard [0, 1, 2].contains(focusRing) else { return 0 }
return focusRing
}
#endif
}
Upvotes: 1
Reputation: 389
In swift you can do
extension UITextView {
#if targetEnvironment(macCatalyst)
@objc(_focusRingType)
var focusRingType: UInt {
return 1 //NSFocusRingTypeNone
}
#endif
}
Upvotes: 21
Reputation: 5145
There is a private method _setFocusRingType:
that appears to match the NSView API. I was able to use that to eliminate the focus ring, though this may not pass app review.
Use this at your own risk:
SEL selector = NSSelectorFromString(@"_setFocusRingType:");
NSMethodSignature *signature = [self.textView methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:selector];
NSUInteger arg = 1; // NSFocusRingTypeNone
[invocation setArgument:&arg atIndex:2];
[invocation invokeWithTarget:self.textView];
Hopefully we get a real solution from Apple.
Upvotes: 1