cocoa - ¿Cómo expandir y contraer partes de NSSplitView mediante programación?
(10)
Quiero reemplazar RBSplitView
con NSSplitView
en mi proyecto existente. Ahora la aplicación es solo para leopard y me gustaría reemplazar RBSplitView
con el nuevo NSSplitView
incluye con Leopard.
Sin embargo, me faltan los métodos prácticos de RBSplitView
para expand
y collapse
en NSSplitView
. ¿Cómo puedo expandir y contraer partes de NSSplitView mediante programación?
Acabo de recibir la expansión programática y el colapso de NSSplitView
para funcionar. También configuré mi NSSplitView
para expandir / contraer una subvista cada vez que se hace doble clic en el divisor, así que quise que esto funcionara bien con esa característica (y parece que sí). Esto es lo que hice:
(en este ejemplo, splitView
es el propio NSSplitView
, splitViewSubViewLeft
es la subvista que deseo expandir / contraer y lastSplitViewSubViewLeftWidth
es una variable de instancia de tipo CGFloat
).
// subscribe to splitView''s notification of subviews resizing
// (I do this in -(void)awakeFromNib)
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(mainSplitViewWillResizeSubviewsHandler:)
name:NSSplitViewWillResizeSubviewsNotification
object:splitView
];
// this is the handler the above snippet refers to
- (void) mainSplitViewWillResizeSubviewsHandler:(id)object
{
lastSplitViewSubViewLeftWidth = [splitViewSubViewLeft frame].size.width;
}
// wire this to the UI control you wish to use to toggle the
// expanded/collapsed state of splitViewSubViewLeft
- (IBAction) toggleLeftSubView:(id)sender
{
[splitView adjustSubviews];
if ([splitView isSubviewCollapsed:splitViewSubViewLeft])
[splitView
setPosition:lastSplitViewSubViewLeftWidth
ofDividerAtIndex:0
];
else
[splitView
setPosition:[splitView minPossiblePositionOfDividerAtIndex:0]
ofDividerAtIndex:0
];
}
Después de experimentar con las sugerencias, esta fue la solución más fácil que encontré:
-(void)toggleCollapsibleView:(ib)sender {
[collapsibleView setHidden:![splitView isSubviewCollapsed:collapsibleView]];
[splitView adjustSubviews];
}
La función es una acción de primer respondedor definida por el usuario. Se activa mediante un elemento de menú (o pulsación de tecla). La vista colapsable es una subvista en la vista dividida, ambas conectadas en IB con sus propiedades.
En El Capitán, esto hizo el truco para mí.
splitViewItem.collapsed = YES;
En macOS Sierra, la propiedad collapsed
se cambia a isCollapsed
. Es sencillo simplemente establecer la propiedad en true
o false
. El siguiente código es de mi WindowController
, donde tengo dos SplitViewItem
s.
@IBAction func toggleMap(_ sender: Any) {
if let splitViewController = contentViewController as? NSSplitViewController {
let splitViewItem = splitViewController.splitViewItems
if splitViewItem.first!.isCollapsed {
splitViewItem.first!.isCollapsed = false
} else if splitViewItem.last!.isCollapsed {
splitViewItem.last!.isCollapsed = false
} else {
if splitViewItem.first!.isCollapsed {
splitViewItem.first!.isCollapsed = false
}
splitViewItem.last!.isCollapsed = true
}
}
}
En veloz esto funciona.
func togglePanel() {
let splitViewItem = self.mySplitView.arrangedSubviews
if mySplitView.isSubviewCollapsed(outline.view){
splitViewItem[0].hidden = false
} else {
splitViewItem[0].hidden = true
}
Llámelo a IBAction, el esquema es un OutlineViewController con su propio xib y necesitamos la vista, por lo tanto, la vista del esquema. Manténgalo simple pero espero que tenga la idea
@IBAction func segmentAction(sender: NSSegmentedControl) {
splitVC?.togglePanel(sender.selectedSegment)
}
y
func togglePanel(segmentID: Int) {
let splitViewItem = self.mySplitView.arrangedSubviews
switch segmentID {
case segmentID:
if mySplitView.isSubviewCollapsed(splitViewItem[segmentID]) {
splitViewItem[segmentID].hidden = false
} else {
splitViewItem[segmentID].hidden = true
}
default:
break
}
}
E implementar delegado
func splitView(splitView: NSSplitView, shouldHideDividerAtIndex dividerIndex: Int) -> Bool {
return true
}
Y con 10.11 puedes usar el método de acción toggleSidebar. ¿Cómo cambiar la visibilidad de NSSplitView subView + hide Pane Splitter divider? https://github.com/Dis3buted/SplitViewController
Probé la solución anterior y encontré que no funcionó, ya que isSubviewCollapsed nunca devolvió SI
Una combinación de las sugerencias produjo un resultado que funciona.
if ([splitViewTop isHidden]) {
[splitViewTop setHidden:NO];
[split
setPosition:previousSplitViewHeight
ofDividerAtIndex:0];
}
else {
[splitViewTop setHidden:YES];
}
[split adjustSubviews];
Puedes probar el BWToolKit Brandon Walkin.
La clase BWSplitView tiene un método.
- (IBAction)toggleCollapse:(id)sender;
Recomiendo usar NSSplitViewController
en NSSplitViewController
lugar, y NSSplitViewItem.isCollapsed
para controlarlos. Esto sólo funciona.
let item: NSSplitViewItem = ...
item.isCollapsed = true
Para que esto funcione correctamente, debe configurar los componentes de la interfaz de usuario dividida con principalmente controladores de vista. De lo contrario, se puede romper.
Simplemente oculte la subvista que desea contraer, por ejemplo,
[aSubViewToCollapse setHidden:YES];
También es posible que desee implementar el método delegado: (BOOL) splitView: shouldHideDividerAtIndex: para devolver YES (SÍ) para ocultar el divisor cuando se contrae.
NSSplitView
realidad tiene un método privado -(void)_setSubview:(NSView *)view isCollapsed:(BOOL)collapsed
hacer esto. Aquellos que deseen ignorar todas las advertencias contra el uso de métodos privados, he aquí:
- (void)toggleSubview:(NSView *)view {
SEL selector = @selector(_setSubview:isCollapsed:);
NSMethodSignature *signature = [NSSplitView instanceMethodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.target = self;
invocation.selector = selector;
[invocation setArgument:&view atIndex:2];
BOOL arg = ![self isSubviewCollapsed:view];
[invocation setArgument:&arg atIndex:3];
[invocation invoke];
}
Implementé esto como una categoría en NSSplitView
. El único problema es que Xcode da una advertencia sobre _setSubview:isCollapsed:
no se _setSubview:isCollapsed:
... No estoy muy seguro de cómo _setSubview:isCollapsed:
.
Actualización de El Capitán
No he escrito ningún código para OS X en ~ 2 años, así que no he podido verificar esto, pero según lemonmojo en los comentarios a continuación, _setSubview:isCollapsed:
fue renombrado en El Capitán a _setArrangedView:isCollapsed: