我有幾個面板包含NSTextField
控件綁定到文件的所有者對象內的屬性。如果用戶編輯了一個字段,然後按標籤,移動到下一個字段,它按預期工作。但是,如果用戶未按選項卡,並且只按下確定按鈕,則文件的所有者對象中未設置新值。可可:避免控制綁定中的'持續更新'
爲了解決這個問題,我已經在綁定中設置了連續更新,但是這必須很貴(編輯:或者至少它不雅)。
有沒有辦法強制綁定更新時,按下確定按鈕而不是使用更新連續?
我有幾個面板包含NSTextField
控件綁定到文件的所有者對象內的屬性。如果用戶編輯了一個字段,然後按標籤,移動到下一個字段,它按預期工作。但是,如果用戶未按選項卡,並且只按下確定按鈕,則文件的所有者對象中未設置新值。可可:避免控制綁定中的'持續更新'
爲了解決這個問題,我已經在綁定中設置了連續更新,但是這必須很貴(編輯:或者至少它不雅)。
有沒有辦法強制綁定更新時,按下確定按鈕而不是使用更新連續?
你說得對,你不需要使用連續更新值選項。
如果您使用綁定(您是),那麼您應該做的是調用管理綁定的NSController
子類的-commitEditing
方法。您通常會在關閉您顯示的工作表的方法中執行此操作。
-commitEditing
告訴控制器在活動控件中完成編輯並將當前編輯提交給綁定對象。
無論何時執行持久性操作(如保存),都可以調用此函數。
那麼這是否意味着你需要一個*出口*到窗格中的每個控件,並且在關閉窗格之前需要在它們的所有窗口上調用'commitEditing'?還是有更簡單的方法來實現這一點? – trojanfoe 2012-04-01 09:01:30
您不要在控件上調用'commitEditing',而是在控件所綁定的'NSController'上調用它。這可能是一個'NSArrayController','NSTreeController'或者簡單的'NSObjectController'。如果你將控件直接綁定到模型對象而不是通過'NSObjectController',那麼你應該改變你的綁定來使用'NSObjectController'作爲中介對象。主要原因是'NSObjectController'將使用'NSEditorRegistration'協議來告訴控件完成編輯,而普通的綁定則不會。 – 2012-04-01 20:53:14
嗯,有趣。這對我來說是新的,在我最初學習Cocoa編程的書中沒有提及。我會研究這一點。使用我的方法是否存在問題(如我的答案中所述)還是被認爲是*破解*? – trojanfoe 2012-04-01 20:56:18
解決方法是在OK按鈕調用的操作方法中「結束編輯」。由於該窗格是NSWindowController
的子類,因此可以輕鬆訪問NSWindow
,但是在您的代碼中,您可能必須通過綁定到控制器的控件獲取NSWindow
;例如NSWindow *window = [_someControl window]
。
以下是我的okPressed
操作方法的實現。
總之我相信這是一個更好的解決在設置不斷更新的綁定控件。
- (IBAction)okPressed:(id)sender
{
NSWindow *window = [self window];
BOOL editingEnded = [window makeFirstResponder:window];
if (!editingEnded)
{
logwrn(@"Unable to end editing");
return;
}
if (_delegateRespondsToEditComplete)
{
[_delegate detailsEditComplete:&_mydetails];
}
}
儘管這確實很老,但我完全不同意這個問題所基於的假設。
不斷更新綁定絕對不貴。我想你可能會認爲這會不斷更新價值,理解爲「定期基於某個時間間隔」。
但這是不正確的。這只是意味着它在每次更改綁定值時都會更新。這意味着,當您在textView中鍵入內容時,它會在您寫入時更新;這是你在這種情況下想要的。
感謝您的評論;然而,這就是全部;這不是一個答案。 – trojanfoe 2016-02-05 07:08:50
是什麼讓你認爲「持續更新」代價昂貴?是嗎?你有個人簡介嗎? – 2012-03-31 00:18:25
好吧,不,像往常一樣Rob,但是它在我的核心C++庫中設置了值,它包括構建'std :: string'對象和'NSString'對象之間的轉換。它看起來很不雅,我認爲一定有更好的辦法。 – trojanfoe 2012-03-31 07:59:19
我同意,只是對性能進行假設並不是一個好主意。過早優化是邪惡的! – 2012-03-31 23:19:40