13

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?

adamfootdev
  • 1,149
  • 10
  • 15
  • 1
    I have the same issue, asked around on Apple Dev Forum, not much response so far: https://forums.developer.apple.com/thread/121280 UIKit started to adopt the focusRing APIs that macOS UI elements have by default (see: https://developer.apple.com/documentation/appkit/nsview/1483261-focusringtype), but there is no public API yet to change the default behaviour. – Peteee24 Aug 23 '19 at 16:21
  • Please don't remove this ring - this is important for accessibility + keyboard only users. – user11145365 Dec 19 '20 at 23:15

7 Answers7

21

In swift you can do


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

Amerino
  • 389
  • 1
  • 5
13

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
}
2

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

megastep
  • 1,246
  • 12
  • 13
1

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.

Adam
  • 4,405
  • 16
  • 23
  • Thanks I’ll take a look at this. It looks like Apple has removed the focus ring for all UI elements apart from UITextViews - including in Apple Catalyst apps. – adamfootdev Sep 07 '19 at 21:02
1

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
}
Steig
  • 173
  • 2
  • 5
1

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

user11145365
  • 184
  • 9
0

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
CristianMoisei
  • 2,071
  • 2
  • 22
  • 28