I am getting this error
2019-08-31 15:23:58.063933-0500 Sidebar Test[38594] xxx3
2019-08-31 15:23:58.073116-0500 Sidebar Test[38594] *** -[AppDelegate tableViewSelectionDidChange:]: Can’t make «class ocid» id «data optr0000000000D189ADFF7F0000» into type Unicode text. (error -1700)
Thanks for the help!
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 tableView:isGroupRow:
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 tableView:shouldSelectRow:
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 tableView:viewForTableColumn:row:
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
log "xxx3"
set oldLabel to item 1 of detailSubviews
log "xx4 "
detailView's replaceSubview:oldLabel |with|:newLabel
else
detailView's addSubview:newLabel
end if
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 tableViewSelectionDidChange:
end script
I assume you were getting this error before you added the ‘log’ statements, and that it occurs right after you click on one of the sidebar items, correct?
The error means literally that xcode thinks you’re trying to convert an objective-c object (in this case, most likely a view) to a text string, but I can’t see where you might be doing that. Could you add a line right after the ‘log “xxx3”’ line that says “log detailSubviews” and see what output you get in Xcode’s console? should look like:
if detailSubviews is not {} then
log "xxx3"
log detailSubviews
set oldLabel to item 1 of detailSubviews
log "xx4 "
detailView's replaceSubview:oldLabel |with|:newLabel
else
[...]
The new error message.
2019-09-01 15:40:47.859006-0500 Sidebar Test[91459] xxx3
2019-09-01 15:40:47.866507-0500 Sidebar Test[91459] *** -[AppDelegate tableViewSelectionDidChange:]: Can’t get subviews. (error -1728)
I think the detail view is setup exactly as described.
property detailView : missing value
Referencing outlet detailView - delegate for the array controller.
There should be a separate (empty) view in the xib connected by a referencing outlet to the property ‘detailView’ in the appDelegate script (using the Delegate object on the left). Is that correct? I’m thinking it’s not connected right, because the 'subviews method should return (at worst) an empty NSArray if the view exists. The “can’t get subviews” makes me think that the property dtailView is unset at that point (still missing value, rather than a reference to a view).
I’ll also note that this error seems to come earlier in execution than the previous error (since we don’t see the ‘xxx3’ log item), even though we changed code that’s later. That’s a bit screwy, and makes me think you should clean and rebuild the project (menu: Project → Clean build folder). Might have some cobwebs gumming things up…
EDIT: sorry, you did get the ‘xxx3’ log. Are you sure you typed ‘detailSubviews’, and not ‘detail subviews’? Typos are an annoying fact of life.
It does appear to not be connected, but its not empty because it makes it into the if statement?
See the spelling as logged.
When I have the array controller selected
the connections inspector shows on
Referencing Outlets
array controller - Delegate
detailView - Delegate
So I removed detailView - Delegate from above.
added
with Detail View selected
connections inspector
Referencing Outlets
detailView - Delegate
Now it shows the first item clicked in the table fine…
but a second click on another item triggers an error
with **log detailSubviews enabled gives this error
2019-09-02 10:42:56.616243-0500 Sidebar Test[36215] (
“<NSTextField: 0x100432400>”
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
*)
log "begin"
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
log "XX2"
log "detailView"
log detailView
log "XX3"
if detailSubviews is not {} then
log "xxx4"
log "detailSubviews"
--**log detailSubviews
log "xxx5"
log "oldLabel"
set oldLabel to item 1 of detailSubviews as text
detailView's replaceSubview:oldLabel |with|:newLabel
log "xxx6"
--log detailView's |class| ()
else
detailView's addSubview:newLabel
end if
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 tableViewSelectionDidChange:
So I discovered I had changed as list to text during troubleshooting.
This line “set oldLabel to item 1 of detailSubviews as text”
now there is this error
2019-09-02 11:22:42.221201-0500 Sidebar Test[37870] *** -[AppDelegate tableViewSelectionDidChange:]: Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x60000067b900 “NSTextField:0x100683340.centerX”> and <NSLayoutXAxisAnchor:0x600000a6a3c0 “NSView:0x600000120aa0.centerX”> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That’s illegal. (error -10000)
set constraintX to newLabel's centerXAnchor's constraintEqualToAnchor:(detailView's centerXAnchor)
and it means that (for some reason we have yet to discover) the label we created (newLabel) has not been added as a subview of the view (detailView). The most likely explanation is that one of the three views involved (oldLabel, newLabel, or detailView) is nil. I’m suspecting it’s oldLabel, because the line where you set oldLabel has been giving you trouble (and if oldLabel is nil, the replaceSubview command won’t do anything). the code should look like this (with the log commands removed):
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 if
Note that in the ‘set oldLabel to…’ line I don’t try to do any coercions. ‘detailSubviews’ (at that point in the code) is an AppleScript list of objective-c view objects (objects that are the subviews of the ‘detailView’ view). We just want to pull out that first view object and replace it with our new object, without changing it in any other way.
It was the connection all along.
This code works!
Thanks!
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 tableView:isGroupRow:
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 tableView:shouldSelectRow:
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 tableView:viewForTableColumn:row:
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 if
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 tableViewSelectionDidChange:
end script