问题
I would like to know how I can create a window with the sidebar, basically what I want is a sidebar that will open some windows by clicking on a name, as in the example below, thanks in advance.
回答1:
Ok, here are the steps for setting up a sidebar in an Xcode AppleScript app. I'm just showing functionality; I'll leave beautification for you to play with.
First (obviously), set up the GUI. Open MainMenu.xib, and add three items from the object library:
- A Table View in the left side of the window (to display the sidebar)
- A Custom View in the right side of the window (to display a detail view)
- An Array Controller in the objects list on the left.
It should look something like this (red annotation for clarity): You'll want to set up layout constraints to keep the sidebar a constant width and keep the custom view glued to its side, but you can play with that.
Now we'll set up bindings and a few other details. First, click of the Array Controller object on the left, and open the Utilities pane on the right.
- Click the 'Attributes' inspector.
- Make sure the Mode is 'class' and the 'class name' is NSMutableDictionary
- Add two names to the 'Keys' section: 'title' and 'isHeader' (these are the keys we'll be using in the dictionaries)
- Unclick 'Select inserted objects', because it's annoying.
Next, click on the Table View in the list, then go again to the Utilities pane on the right.
- Click the 'Attributes' inspector and set the number of columns to 1.
- Click the 'Bindings' inspector, go down to the Table Content section, and create two bindings:
- In Content click the Bind to checkbox, choose Array Controller from the popup, and make sure that the Controller Key is arrangedObjects
- In Selection Indexes make the same object binding but use selectionIndexes for the Controller Key.
- Click the 'Connections' inspector, and drag from the delegate outlet to the Delegate object on the left, so that the table view will use the AppDelegate script as its table view delegate.
Next, click on the Table Cell View in the list, and again to the Utilities pane.
- Click the 'Identity' inspector and set the identifier to 'tableItem' (without the quotes). This lets the delegate find this particular view and pass it on to the table.
Finally, click on the Table View Cell object on the left (not the Table Cell View object just above it, or the second Table View Cell just below it: confusing, I know), and go to the Utilities pane on the right, again.
- Click the 'Bindings' inspector, go to the Value section at top, and create one binding:
- In Value click the Bind to checkbox, choose Table Cell View from the popup, leave the Controller Key blank, and set the Model Key Path to objectValue.title
The way this works is that we'll dump a list of dictionaries into the Array Controller, the Table View will pick that up and dole out one dictionary to each Table Cell View as its objectValue, and then the Table View Cells will extract the data and present it.
We're done with the GUI, except for connecting it the script. Now, go to the AppDelegate script that Xcode provided, and you'll want to change it to look like so:
script AppDelegate
property parent : class "NSObject"
-- IBOutlets
property theWindow : missing value
property arrayController : missing value
property detailView : missing value
on applicationWillFinishLaunching_(aNotification)
-- Insert code here to initialize your application before any files are opened
(* set up list of headers and lines for the side bar *)
set sidebarList to {{title:"Header 1", isHeader:true}, {title:"Line 1", isHeader:false}, {title:"Header 2", isHeader:true}, {title:"Line 2", isHeader:false}, {title:"Line 3", isHeader:false}, {title:"Header 3", isHeader:true}, {title:"Line 4", isHeader:false}}
arrayController's addObjects:sidebarList
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return current application's NSTerminateNow
end applicationShouldTerminate_
(* table view delegate emthods *)
on tableView:tableView isGroupRow:row
-- header rows are group rows
set rowData to arrayController's arrangedObjects's objectAtIndex:row
return rowData's isHeader
end
on tableView:tableView shouldSelectRow:row
-- don't want to select header rows
set rowData to arrayController's arrangedObjects's objectAtIndex:row
return not (rowData's isHeader)
end
on tableView:tableView viewForTableColumn:column row:row
-- header rows get a special look
set aView to tableView's makeViewWithIdentifier:"tableItem" owner:me
return aView
end
on tableViewSelectionDidChange:aNotification
(*
This is method gets notified right after a selection is made. This is one of
the places where you can change the detail view to show a the correct view for
selected sidebar item. For demonstration purposes I'm just swapping out
TextField views with the name of the sidebar item. Not to sophisticated,
but it get the point across
*)
set tableView to aNotification's object
set selectedRowIdx to (tableView's selectedRow) as integer
set rowData to arrayController's arrangedObjects's objectAtIndex:selectedRowIdx
set newLabel to current application's NSTextField's labelWithString:(rowData's title )
set newLabel's translatesAutoresizingMaskIntoConstraints to false
set detailSubviews to (detailView's subviews) as list
if detailSubviews is not {} then
set oldLabel to item 1 of detailSubviews
detailView's replaceSubview:oldLabel |with|:newLabel
else
detailView's addSubview:newLabel
end
set constraintX to newLabel's centerXAnchor's constraintEqualToAnchor:(detailView's centerXAnchor)
set constraintY to newLabel's centerYAnchor's constraintEqualToAnchor:(detailView's centerYAnchor)
constraintX's setActive:true
constraintY's setActive:true
end
end script
I added two properties — arrayController and detailView, both with the value 'missing value' (which indicates they are IBOutlets) — that we'll link up to the GUI. I've added two lines in applicationWillFinishLaunching_
to create a list of records and add it to the Array Controller, and the rest are delegate methods that the Table View calls.
To link up the GUI, go back to MainMenu.xib, click on the Array Controller object, open the 'Connections' inspector in the Utilities pane, and drag a New Referencing Outlet to the Delegate object, connecting it with the property arrayController. Do the same for the Custom View, connecting it to the property detailView. You should be good to go.
回答2:
What you are looking for is a sidebar / source list - you can take a look at Apple’s older SidebarDemo sample project for an example of something fairly small using an outline view (might even be relatively easy to translate to ASObjC).
Depending on what you are ultimately wanting to do, I suppose it could be done with AppleScript, but I think you will find that the bigger the application, the bigger a pain it is. AppleScript is great for prototyping and controlling other applications, but not so much when things start getting large or complex (e..g. your previous experiences with sheets). If you are planning on doing applications that are a bit more serious, you might look into using a language that is also a bit more serious.
来源:https://stackoverflow.com/questions/57384941/how-to-use-a-sidebar-with-applescript