Blue Highlighting / Focus Ring on Catalyst App

3.2k Views Asked by At

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?

7

There are 7 best solutions below

3
 Amerino On BEST ANSWER

In swift you can do


extension UITextView {
    #if targetEnvironment(macCatalyst)
    @objc(_focusRingType)
    var focusRingType: UInt {
        return 1 //NSFocusRingTypeNone
    }
    #endif
}

1
Adam On

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.

0
Steig On

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
}
2
Dmitry Frantskevich On

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
}
0
megastep On

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:

enter image description here

1
user11145365 On

Please don't do this - this is a focus indicator for accessibility and is important for keyboard-only users.

0
CristianMoisei On

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