{"id":3352,"date":"2023-06-11T16:29:10","date_gmt":"2023-06-11T20:29:10","guid":{"rendered":"https:\/\/michaelrowe01.com\/?p=3352"},"modified":"2023-06-11T16:29:12","modified_gmt":"2023-06-11T20:29:12","slug":"the-swiftui-cookbook-for-focus","status":"publish","type":"post","link":"https:\/\/michaelrowe01.com\/index.php\/blog\/the-swiftui-cookbook-for-focus\/","title":{"rendered":"The SwiftUI cookbook for focus"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"660\" height=\"371\" data-attachment-id=\"3353\" data-permalink=\"https:\/\/michaelrowe01.com\/index.php\/blog\/the-swiftui-cookbook-for-focus\/attachment\/the-swiftui-cookbook\/\" data-orig-file=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?fit=1920%2C1080&amp;ssl=1\" data-orig-size=\"1920,1080\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"The-SwiftUI-cookbook\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?fit=660%2C371&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?resize=660%2C371&#038;ssl=1\" alt=\"\" class=\"wp-image-3353\" srcset=\"https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?resize=1024%2C576&amp;ssl=1 1024w, https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?resize=300%2C169&amp;ssl=1 300w, https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?resize=768%2C432&amp;ssl=1 768w, https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?resize=1536%2C864&amp;ssl=1 1536w, https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?w=1920&amp;ssl=1 1920w, https:\/\/i0.wp.com\/michaelrowe01.com\/wp-content\/uploads\/2023\/06\/The-SwiftUI-cookbook.png?w=1320&amp;ssl=1 1320w\" sizes=\"auto, (max-width: 660px) 100vw, 660px\" \/><\/figure>\n\n\n\n<p>Using Focus API\u2019s in SwiftUI<\/p>\n\n\n\n<p>What is Focus<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>This is a tool to decide how to respond when someone interacts with an input method.&nbsp; On their own they don\u2019t provide enough information on which onscreen control to interact with.<\/li>\n\n\n\n<li>When a view has focus, the system will use it as a starting point to react to input&nbsp;<\/li>\n\n\n\n<li>It has a border on macOS, watchOS has a green border, and on tvOS it will hover above the UI<\/li>\n\n\n\n<li>Helps users understand where input will go, it\u2019s a special kind of cursor<\/li>\n\n\n\n<li>It is a cursor for the user\u2019s attention<\/li>\n<\/ul>\n\n\n\n<p>Ingredients<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Focusable views\n<ul class=\"wp-block-list\">\n<li>Different views are focusable for different reasons.&nbsp; Text fields are always focusable.&nbsp; Buttons are used for clicks and taps, you need keyboard navigation system wide to allow for buttons to be tab able.<\/li>\n\n\n\n<li>Buttons support focus for activation.&nbsp; In iOS 17 and macOS Sonoma &#8211; there are new view modifier to define the types of interactions you support.&nbsp; .focusable(interactions: .edit) or .focusable(interactions: .activate).&nbsp; If you don\u2019t define an interaction, you will get the .all value. Prior to macOS Sonoma the system only used .activate focus modifier.&nbsp; (I should add focusable in my code)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Focus state\n<ul class=\"wp-block-list\">\n<li>The system keeps track of which view has focus &#8211; this is @FocusState bindings -it is a bool (or custom data types for more complex interactions)<\/li>\n\n\n\n<li>Views can read this to understand when they are in focus or not.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Focused values\n<ul class=\"wp-block-list\">\n<li>This solves data dependencies that link remote parts of your application.&nbsp; This is like using a custom environment key and values.&nbsp; Set up a getter and setter, and define view Modifiers to address this<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Focus sections\n<ul class=\"wp-block-list\">\n<li>Gives you a way to influence how things move when people swipe on a remote or hit tab&nbsp; on a keyboard.&nbsp; This follows the layout order of the locale on a keyboard. But directional on Apple TV remote.<\/li>\n\n\n\n<li>You use .focusSection() to guide focus to the nearest focusable content.&nbsp; You will need to add spacers to align content.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Recipes<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>For custom controls you should consider which items to focus on when lists appear. &nbsp; The Grocery list example in this session explains how to do this with @FocusState and .defaultFocus()<\/li>\n\n\n\n<li>If you want the app to move focus programmatically you can use the same example of adding a new item to the list\n<ul class=\"wp-block-list\">\n<li>I should address focus in my Wasted Time app for updates on the settings screen<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>If you create a custom control, the custom picker example helps with this pattern.\n<ul class=\"wp-block-list\">\n<li>Remember to turn on Keyboard navigation systemwide<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Focusable grid view is the final receipt &#8211; using Lazy Grid<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Using Focus API\u2019s in SwiftUI What is Focus Ingredients Recipes<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"hide_page_title":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[2,3],"tags":[752,766,759,680],"class_list":["post-3352","post","type-post","status-publish","format-standard","hentry","category-blog","category-personal-softwareandit","tag-day-7","tag-focus","tag-keyboard","tag-wwdc23"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p2aMa8-S4","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts\/3352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/comments?post=3352"}],"version-history":[{"count":1,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts\/3352\/revisions"}],"predecessor-version":[{"id":3354,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/posts\/3352\/revisions\/3354"}],"wp:attachment":[{"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/media?parent=3352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/categories?post=3352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaelrowe01.com\/index.php\/wp-json\/wp\/v2\/tags?post=3352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}