├── images └── logo.png ├── Symbol Instance Renamer.sketchplugin └── Contents │ ├── Resources │ └── icon.png │ └── Sketch │ ├── manifest.json │ └── script.js ├── appcast.xml ├── LICENSE.md └── README.md /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonburn/symbol-instance-renamer/HEAD/images/logo.png -------------------------------------------------------------------------------- /Symbol Instance Renamer.sketchplugin/Contents/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonburn/symbol-instance-renamer/HEAD/Symbol Instance Renamer.sketchplugin/Contents/Resources/icon.png -------------------------------------------------------------------------------- /appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Symbol Instance Renamer 5 | http://sparkle-project.org/files/sparkletestcast.xml 6 | Rename all symbol instances to the name of their master. 7 | en 8 | 9 | Version 2.9 10 | 11 | 13 |
  • Fix for Sketch 72.
  • 14 | 15 | ]]> 16 |
    17 | 18 |
    19 |
    20 |
    21 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jason Burns (Sonburn) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Symbol Instance Renamer](https://raw.githubusercontent.com/sonburn/symbol-instance-renamer/master/images/logo.png) 2 | 3 | Rename symbol instances to the name of their master. 4 | 5 | [![Symbol Instance Renamer](https://img.youtube.com/vi/_L7E0B3y9d0/0.jpg)](https://www.youtube.com/watch?v=_L7E0B3y9d0) 6 | 7 | 8 | runner-badge-blue 9 | 10 | 11 | 12 | 13 | 14 | 15 | # Usage 16 | 17 | * cmd option shift d - Rename all symbol instances on all pages to the name of their master 18 | * cmd option shift x - Rename all symbol instances on all pages, except the Symbols page, to the name of their master 19 | * cmd option shift p - Rename all symbol instances on current page to the name of their master 20 | * cmd option shift a - Rename all symbol instances in selected artboards to the name of their master 21 | * cmd option shift m - Rename all instances of the selected symbols to the name of their master 22 | * cmd option shift s - Rename selected symbol instances to the name of their master 23 | 24 | ## Automatic 25 | Search for Symbol Instance Renamer in [Sketchrunner](http://sketchrunner.com/) or [Sketch Toolbox](http://sketchtoolbox.com/) if you have one of those installed. 26 | 27 | Once installed, Sketch will automatically notify you when an update is available (version 2.2 and later). 28 | 29 | ## Manual 30 | 31 | 1. Download and open symbol-instance-renamer-master.zip 32 | 2. Navigate to Symbol Instance Renamer.sketchplugin and copy/move to your plugins directory 33 | 34 | To find your plugins directory... 35 | 36 | 1. In the Sketch menu, navigate to Plugins > Manage Plugins... 37 | 2. Click the cog in the lower left of the plugins window, and click Reveal Plugins Folder 38 | 39 | # Changelog 40 | 41 | * **2.9** - Fix for Sketch 72. 42 | * **2.8** - Fixed 'Rename Selected Instance(s) with Options', and added handling for when a symbol instance's master is missing. 43 | * **2.7** - Update for Sketch 53. 44 | * **2.6** - Added new function to rename selected instances with additional options, and added plugin icon to manifest for Sketch 50. 45 | * **2.5** - Added new function to rename all instances within selected artboard(s). 46 | * **2.4** - Added new function to rename all instances of selected symbol(s). 47 | * **2.3** - Added new function to rename all instances on all pages, except Symbols page. Added fix for when the master for an instance is missing. 48 | * **2.2** - Added appcast plugin support for Sketch 45 and later. Added new function to rename all instances on current page. New shortcuts. 49 | 50 | # Contact 51 | 52 | Find me on Twitter @sonburn 53 | 54 | # Support 55 | 56 | If you find this plugin helpful, or would like to support my plugins in general, buy me ☕️ via PayPal. 57 | 58 | # License 59 | 60 | Copyright (c) 2021 Jason Burns (Sonburn). See LICENSE.md for further details. 61 | -------------------------------------------------------------------------------- /Symbol Instance Renamer.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "Symbol Instance Renamer", 3 | "description" : "Rename symbol instances to the name of their master.", 4 | "author" : "Jason Burns", 5 | "homepage" : "https://github.com/sonburn/symbol-instance-renamer", 6 | "version" : "2.9", 7 | "identifier" : "com.sonburn.sketchplugins.symbol-instance-renamer", 8 | "appcast" : "https://raw.githubusercontent.com/sonburn/symbol-instance-renamer/master/appcast.xml", 9 | "icon" : "icon.png", 10 | "commands" : [ 11 | { 12 | "name" : "Rename All Instances on All Pages", 13 | "shortcut" : "cmd option shift d", 14 | "identifier" : "renameEverything", 15 | "description" : "Rename all symbol instances on all pages to the name of their master.", 16 | "icon" : "icon.png", 17 | "script" : "script.js", 18 | "handler" : "renameEverything" 19 | }, 20 | { 21 | "name" : "Rename All Instances on All Pages (Except Symbols Page)", 22 | "shortcut" : "cmd option shift x", 23 | "identifier" : "renamePages", 24 | "description" : "Rename all symbol instances on all pages, except the Symbols page, to the name of their master.", 25 | "icon" : "icon.png", 26 | "script" : "script.js", 27 | "handler" : "renamePages" 28 | }, 29 | { 30 | "name" : "Rename All Instances on Current Page", 31 | "shortcut" : "cmd option shift p", 32 | "identifier" : "renamePage", 33 | "description" : "Rename all symbol instances on current page to the name of their master.", 34 | "icon" : "icon.png", 35 | "script" : "script.js", 36 | "handler" : "renamePage" 37 | }, 38 | { 39 | "name" : "Rename All Instances in Selected Artboard(s)", 40 | "shortcut" : "cmd option shift a", 41 | "identifier" : "renameArtboard", 42 | "description" : "Rename all symbol instances in selected artboards to the name of their master.", 43 | "icon" : "icon.png", 44 | "script" : "script.js", 45 | "handler" : "renameArtboard" 46 | }, 47 | { 48 | "name" : "Rename All Instances of Selected Symbol(s)", 49 | "shortcut" : "cmd option shift m", 50 | "identifier" : "renameSymbol", 51 | "description" : "Rename all instances of the selected symbols to the name of their master.", 52 | "icon" : "icon.png", 53 | "script" : "script.js", 54 | "handler" : "renameSymbol" 55 | }, 56 | { 57 | "name" : "Rename Selected Instance(s)", 58 | "shortcut" : "cmd option shift s", 59 | "identifier" : "renameSelected", 60 | "description" : "Rename selected symbol instances to the name of their master.", 61 | "icon" : "icon.png", 62 | "script" : "script.js", 63 | "handler" : "renameSelected" 64 | }, 65 | { 66 | "name" : "Rename Selected Instance(s) with Options…", 67 | "identifier" : "renameSelectedOptions", 68 | "description" : "Rename instances with additional options.", 69 | "icon" : "icon.png", 70 | "script" : "script.js", 71 | "handler" : "renameSelectedOptions" 72 | }, 73 | { 74 | "name" : "Report Issue", 75 | "identifier" : "report", 76 | "description" : "Report an issue with Symbol Instance Renamer.", 77 | "icon" : "icon.png", 78 | "script" : "script.js", 79 | "handler" : "report" 80 | }, 81 | { 82 | "name" : "Other Plugins", 83 | "identifier" : "plugins", 84 | "description" : "View all of Sonburn's plugins.", 85 | "icon" : "icon.png", 86 | "script" : "script.js", 87 | "handler" : "plugins" 88 | }, 89 | { 90 | "name" : "Donate", 91 | "identifier" : "donate", 92 | "description" : "Donate to the development of Symbol Instance Renamer.", 93 | "icon" : "icon.png", 94 | "script" : "script.js", 95 | "handler" : "donate" 96 | } 97 | ], 98 | "menu" : { 99 | "title" : "Symbol Instance Renamer", 100 | "items" : [ 101 | "renameEverything", 102 | "renamePages", 103 | "renamePage", 104 | "renameArtboard", 105 | "renameSymbol", 106 | "renameSelected", 107 | "renameSelectedOptions", 108 | "-", 109 | "report", 110 | "plugins", 111 | "donate" 112 | ] 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Symbol Instance Renamer.sketchplugin/Contents/Sketch/script.js: -------------------------------------------------------------------------------- 1 | const sketch = require("sketch"); 2 | 3 | var strPluginName = "Symbol Instance Renamer", 4 | strRenameSuccess = " symbol instances have been renamed", 5 | strRenameFailure = "Select at least one symbol instance to rename.", 6 | strRenameFailureArtboard = "Select at least one artboard for which to rename instances.", 7 | strRenameFailureSymbol = "Select at least one symbol master for which to rename instances.", 8 | strRenameFailureString = "Provide a new name for the selected instances.", 9 | debugMode = false; 10 | 11 | var renameEverything = function(context) { 12 | var pages = context.document.pages(), 13 | pageLoop = pages.objectEnumerator(), 14 | page, 15 | count = 0; 16 | 17 | while (page = pageLoop.nextObject()) { 18 | count = count + renameObjectInstances(page); 19 | } 20 | 21 | sketch.UI.message(count + strRenameSuccess); 22 | 23 | if (!debugMode) googleAnalytics(context,"rename","everything"); 24 | } 25 | 26 | var renamePages = function(context) { 27 | var pages = context.document.pages(), 28 | pageLoop = pages.objectEnumerator(), 29 | page, 30 | count = 0; 31 | 32 | while (page = pageLoop.nextObject()) { 33 | if (page != context.document.documentData().symbolsPage()) { 34 | count = count + renameObjectInstances(page); 35 | } 36 | } 37 | 38 | sketch.UI.message(count + strRenameSuccess); 39 | 40 | if (!debugMode) googleAnalytics(context,"rename","pages"); 41 | } 42 | 43 | var renamePage = function(context) { 44 | var count = renameObjectInstances(context.document.currentPage()); 45 | 46 | sketch.UI.message(count + strRenameSuccess); 47 | 48 | if (!debugMode) googleAnalytics(context,"rename","page"); 49 | } 50 | 51 | var renameArtboard = function(context) { 52 | var predicate = NSPredicate.predicateWithFormat("className == %@","MSArtboardGroup"), 53 | artboards = context.selection.filteredArrayUsingPredicate(predicate), 54 | artboardLoop = artboards.objectEnumerator(), 55 | artboard, 56 | count = 0; 57 | 58 | if (artboards.count() > 0) { 59 | while (artboard = artboardLoop.nextObject()) { 60 | count = count + renameObjectInstances(artboard); 61 | } 62 | 63 | sketch.UI.message(count + strRenameSuccess); 64 | 65 | if (!debugMode) googleAnalytics(context,"rename","artboard"); 66 | } else { 67 | sketch.UI.alert(strPluginName,strRenameFailureArtboard); 68 | } 69 | } 70 | 71 | var renameSymbol = function(context) { 72 | var predicate = NSPredicate.predicateWithFormat("className == %@","MSSymbolMaster"), 73 | symbols = context.selection.filteredArrayUsingPredicate(predicate), 74 | symbolLoop = symbols.objectEnumerator(), 75 | symbol, 76 | count = 0; 77 | 78 | if (symbols.count() > 0) { 79 | while (symbol = symbolLoop.nextObject()) { 80 | var instances = symbol.allInstances(), 81 | instanceLoop = instances.objectEnumerator(), 82 | instance; 83 | 84 | while (instance = instanceLoop.nextObject()) { 85 | if (renameInstance(instance)) count++; 86 | } 87 | } 88 | 89 | sketch.UI.message(count + strRenameSuccess); 90 | 91 | if (!debugMode) googleAnalytics(context,"rename","symbol"); 92 | } else { 93 | sketch.UI.alert(strPluginName,strRenameFailureSymbol); 94 | } 95 | } 96 | 97 | var renameSelected = function(context) { 98 | var predicate = NSPredicate.predicateWithFormat("className == %@","MSSymbolInstance"), 99 | instances = context.selection.filteredArrayUsingPredicate(predicate), 100 | instanceLoop = instances.objectEnumerator(), 101 | instance, 102 | count = 0; 103 | 104 | if (instances.count() > 0) { 105 | while (instance = instanceLoop.nextObject()) { 106 | if (renameInstance(instance)) count++; 107 | } 108 | 109 | sketch.UI.message(count + strRenameSuccess); 110 | 111 | if (!debugMode) googleAnalytics(context,"rename","instance"); 112 | } else { 113 | sketch.UI.alert(strPluginName,strRenameFailure); 114 | } 115 | } 116 | 117 | var renameSelectedOptions = function(context) { 118 | var predicate = NSPredicate.predicateWithFormat("className == %@","MSSymbolInstance"), 119 | selections = context.selection.filteredArrayUsingPredicate(predicate), 120 | selectionLoop = selections.objectEnumerator(), 121 | selection, 122 | count = 0; 123 | 124 | if (selections.count() > 0) { 125 | var alertWindow = COSAlertWindow.new(), 126 | iconPath = context.plugin.urlForResourceNamed("icon.png").path(), 127 | icon = NSImage.alloc().initByReferencingFile(iconPath), 128 | renameSource = createRadios(["Use symbol master name","Use other name…"],0), 129 | renameTo = createField("",""), 130 | renameSiblings = createCheckbox({name:"Rename all instances of selected instances",value:1},0), 131 | renameMaster = createCheckbox({name:"Rename symbol master (local name only)",value:1},1), 132 | buttonRename = alertWindow.addButtonWithTitle("Rename"), 133 | buttonCancel = alertWindow.addButtonWithTitle("Cancel"); 134 | 135 | renameSource.cells().objectAtIndex(0).setAction("callAction:"); 136 | renameSource.cells().objectAtIndex(0).setCOSJSTargetFunction(function(sender) { 137 | renameTo.setEnabled(0); 138 | renameMaster.setEnabled(0); 139 | }); 140 | 141 | renameSource.cells().objectAtIndex(1).setAction("callAction:"); 142 | renameSource.cells().objectAtIndex(1).setCOSJSTargetFunction(function(sender) { 143 | renameTo.setEnabled(1); 144 | renameTo.becomeFirstResponder(); 145 | renameMaster.setEnabled(1); 146 | }); 147 | 148 | alertWindow.setIcon(icon); 149 | alertWindow.setMessageText(strPluginName); 150 | alertWindow.setInformativeText("Rename selected symbol instances..."); 151 | alertWindow.addAccessoryView(renameSource); 152 | alertWindow.addAccessoryView(renameTo); 153 | alertWindow.addAccessoryView(renameMaster); 154 | alertWindow.addAccessoryView(renameSiblings); 155 | 156 | renameTo.setEnabled(0); 157 | renameMaster.setEnabled(0); 158 | 159 | setKeyOrder(alertWindow,[ 160 | renameSource, 161 | renameTo, 162 | renameMaster, 163 | renameSiblings, 164 | buttonRename 165 | ]); 166 | 167 | var alertResponse = alertWindow.runModal(); 168 | 169 | if (alertResponse == 1000) { 170 | if (renameSource.selectedCell().tag() == 1 && renameTo.stringValue() == "") { 171 | sketch.UI.alert(strPluginName,strRenameFailureString); 172 | } else { 173 | var name = (renameTo.stringValue() != "") ? renameTo.stringValue() : false, 174 | count = 0; 175 | 176 | if (renameSiblings.state() == 1) { 177 | var masters = NSMutableArray.array(); 178 | 179 | while (selection = selectionLoop.nextObject()) { 180 | var master = selection.symbolMaster(); 181 | 182 | if (!masters.containsObject(master)) { 183 | masters.addObject(master); 184 | } 185 | } 186 | 187 | var masterLoop = masters.objectEnumerator(), 188 | master; 189 | 190 | while (master = masterLoop.nextObject()) { 191 | var instances = master.allInstances(), 192 | instanceLoop = instances.objectEnumerator(), 193 | instance; 194 | 195 | while (instance = instanceLoop.nextObject()) { 196 | if (renameInstance(instance,name)) count++; 197 | } 198 | 199 | if (renameSource.selectedCell().tag() == 1 && renameMaster.state() == 1) { 200 | master.setName(name); 201 | } 202 | } 203 | } else { 204 | while (selection = selectionLoop.nextObject()) { 205 | if (renameInstance(selection,name)) count++; 206 | 207 | if (renameSource.selectedCell().tag() == 1 && renameMaster.state() == 1) { 208 | selection.symbolMaster().setName(name); 209 | } 210 | } 211 | } 212 | 213 | sketch.UI.message(count + strRenameSuccess); 214 | 215 | if (!debugMode) googleAnalytics(context,"rename","instanceOptions"); 216 | } 217 | } else return false; 218 | } else { 219 | sketch.UI.alert(strPluginName,strRenameFailure); 220 | } 221 | } 222 | 223 | var report = function(context) { 224 | openUrl("https://github.com/sonburn/symbol-instance-renamer/issues/new"); 225 | 226 | if (!debugMode) googleAnalytics(context,"report","report"); 227 | } 228 | 229 | var plugins = function(context) { 230 | openUrl("https://sonburn.github.io/"); 231 | 232 | if (!debugMode) googleAnalytics(context,"plugins","plugins"); 233 | } 234 | 235 | var donate = function(context) { 236 | openUrl("https://www.paypal.me/sonburn"); 237 | 238 | if (!debugMode) googleAnalytics(context,"donate","donate"); 239 | } 240 | 241 | function createCheckbox(item,flag,frame) { 242 | var frame = (frame) ? frame : NSMakeRect(0,0,300,16), 243 | checkbox = NSButton.alloc().initWithFrame(frame), 244 | flag = (flag == false) ? NSOffState : NSOnState; 245 | 246 | checkbox.setButtonType(NSSwitchButton); 247 | checkbox.setBezelStyle(0); 248 | checkbox.setTitle(item.name); 249 | checkbox.setTag(item.value); 250 | checkbox.setState(flag); 251 | 252 | return checkbox; 253 | } 254 | 255 | function createField(string,placeholder,frame) { 256 | var frame = (frame) ? frame : NSMakeRect(0,0,300,24), 257 | field = NSTextField.alloc().initWithFrame(frame); 258 | 259 | field.setStringValue(string); 260 | field.setPlaceholderString(placeholder); 261 | 262 | return field; 263 | } 264 | 265 | function createRadios(options,selected,format,x,y) { 266 | var rows = options.length, 267 | columns = 1, 268 | matrixWidth = 300, 269 | cellWidth = matrixWidth, 270 | x = (x) ? x : 0, 271 | y = (y) ? y : 0; 272 | 273 | if (format && format != 0) { 274 | rows = options.length / 2; 275 | columns = 2; 276 | matrixWidth = 300; 277 | cellWidth = matrixWidth / columns; 278 | } 279 | 280 | var cell = NSButtonCell.alloc().init(); 281 | 282 | cell.setButtonType(NSRadioButton); 283 | 284 | var matrix = NSMatrix.alloc().initWithFrame_mode_prototype_numberOfRows_numberOfColumns( 285 | NSMakeRect(x,y,matrixWidth,rows*20), 286 | NSRadioModeMatrix, 287 | cell, 288 | rows, 289 | columns 290 | ); 291 | 292 | matrix.setCellSize(NSMakeSize(cellWidth,20)); 293 | 294 | for (i = 0; i < options.length; i++) { 295 | matrix.cells().objectAtIndex(i).setTitle(options[i]); 296 | matrix.cells().objectAtIndex(i).setTag(i); 297 | } 298 | 299 | matrix.selectCellAtRow_column(selected,0); 300 | 301 | return matrix; 302 | } 303 | 304 | function createSelect(items,selected,frame) { 305 | var comboBox = NSComboBox.alloc().initWithFrame(frame), 306 | selected = (selected > -1) ? selected : 0; 307 | 308 | comboBox.addItemsWithObjectValues(items); 309 | comboBox.selectItemAtIndex(selected); 310 | comboBox.setNumberOfVisibleItems(16); 311 | comboBox.setCompletes(1); 312 | 313 | return comboBox; 314 | } 315 | 316 | function googleAnalytics(context,category,action,label,value) { 317 | var trackingID = "UA-118918252-1", 318 | uuidKey = "google.analytics.uuid", 319 | uuid = NSUserDefaults.standardUserDefaults().objectForKey(uuidKey); 320 | 321 | if (!uuid) { 322 | uuid = NSUUID.UUID().UUIDString(); 323 | NSUserDefaults.standardUserDefaults().setObject_forKey(uuid,uuidKey); 324 | } 325 | 326 | var url = "https://www.google-analytics.com/collect?v=1"; 327 | // Tracking ID 328 | url += "&tid=" + trackingID; 329 | // Source 330 | url += "&ds=sketch" + sketch.version.sketch; 331 | // Client ID 332 | url += "&cid=" + uuid; 333 | // pageview, screenview, event, transaction, item, social, exception, timing 334 | url += "&t=event"; 335 | // App Name 336 | url += "&an=" + encodeURI(context.plugin.name()); 337 | // App ID 338 | url += "&aid=" + context.plugin.identifier(); 339 | // App Version 340 | url += "&av=" + context.plugin.version(); 341 | // Event category 342 | url += "&ec=" + encodeURI(category); 343 | // Event action 344 | url += "&ea=" + encodeURI(action); 345 | // Event label 346 | if (label) { 347 | url += "&el=" + encodeURI(label); 348 | } 349 | // Event value 350 | if (value) { 351 | url += "&ev=" + encodeURI(value); 352 | } 353 | 354 | var session = NSURLSession.sharedSession(), 355 | task = session.dataTaskWithURL(NSURL.URLWithString(NSString.stringWithString(url))); 356 | 357 | task.resume(); 358 | } 359 | 360 | function openUrl(url) { 361 | NSWorkspace.sharedWorkspace().openURL(NSURL.URLWithString(url)); 362 | } 363 | 364 | function renameInstance(instance,name) { 365 | if (instance.symbolMaster()) { 366 | if (name) { 367 | instance.setName(name); 368 | return true; 369 | } else if (instance.name() != instance.symbolMaster().name().trim()) { 370 | instance.setName(instance.symbolMaster().name()); 371 | return true; 372 | } else return false; 373 | } else { 374 | log(instance.name() + ' might have a missing symbol master'); 375 | } 376 | } 377 | 378 | function renameObjectInstances(object) { 379 | var predicate = NSPredicate.predicateWithFormat("className == %@","MSSymbolInstance"), 380 | instances = object.children().filteredArrayUsingPredicate(predicate), 381 | instanceLoop = instances.objectEnumerator(), 382 | instance, 383 | count = 0; 384 | 385 | while (instance = instanceLoop.nextObject()) { 386 | if (renameInstance(instance)) count++; 387 | } 388 | 389 | return count; 390 | } 391 | 392 | function setKeyOrder(alert,order) { 393 | for (var i = 0; i < order.length; i++) { 394 | var thisItem = order[i], 395 | nextItem = order[i+1]; 396 | 397 | if (nextItem) thisItem.setNextKeyView(nextItem); 398 | } 399 | 400 | alert.alert().window().setInitialFirstResponder(order[0]); 401 | } 402 | --------------------------------------------------------------------------------