gpt4 book ai didi

macos - 在 OS X Cocoa 中实现 iOS 密码输入 View

转载 作者:行者123 更新时间:2023-12-03 16:42:01 25 4
gpt4 key购买 nike

我需要在 OS X Cocoa 中创建一个 View ,隐藏除最后输入的字符之外的所有字符(直到该字符在设定的时间后隐藏)。本质上,我想在 OS X Cocoa 中使用带有 textfield.secureTextEntry = YESUITextField

我找不到在 OS X Cocoa 中导入 UITextField 的方法。我认为无论如何这是不可能的,因为 NSTextFieldUITextField 来自两个不同的框架。

OS X Cocoa 中的

NSSecureTextField 不会在设定的时间内保持最后一个字符可见,并且我找不到可以设置来更改此行为的实例或类属性。

我尝试推出自己的实现,从 NSTextField 开始并从 keyUp: 触发事件,但我遇到了极端情况的问题。我当前的方法是将 NSTextField 中存储的文本更改为隐藏字符(除了最后一个字符之外的所有字符,在设定的时间内等)。然而,使用这种技术,当用户选择 7 个字符密码中的第二个到第五个字符并将其删除时会发生什么。那么我怎样才能找出哪些隐藏字符被删除,以便我可以检索正确输入的密码?

因此,我认为如果我需要推出自己的实现,我不需要更改存储在 NSTextField 中的实际文本,而是更改 View 在屏幕上显示的方式。但是我目前找不到办法做到这一点。在此提供帮助将不胜感激。

我还要说的是,我有强烈的偏见,不愿意推出自己的实现。如果有人知道我可以利用以前的工作或简单地将 UITextField 导入 OS X Cocoa 来解决这个问题,我会欢迎(并强烈支持)这些解决方案。

最佳答案

使用NSTextField,我无法成功地将文本的绘制与存储的文本分开。我尝试自定义 NSFormatter 并简要研究了自定义字段编辑器。我得到的最接近的是通过自定义drawInteriorWithFrame:inView:。这使我能够控制绘图,但仅限于字段编辑器无法控制对象时(即,仅当不编辑对象中的文本时)。对于我想要做的事情来说,所有方法似乎都过于复杂。

使用NSTextView我能够让它工作。方法是将字符的绘制与存储的字符分开,并将实际的文本存储在对象中。绘图方法只是在必要时使用星号来隐藏文本,这不会影响存储在对象中的文本值。

这里有一些使用这种方法的代码。它是在 Clozure Common Lisp 中实现的,通过 Clozure 的 Objective C 桥与 Cocoa 进行通信:

(defclass easygui::cocoa-password-entry-text-view (easygui::cocoa-text-view)
((pending-fun :accessor pending-fun :initform nil)
(visible-char-time-secs :reader visible-char-time-secs :initform 1))
(:metaclass ns:+ns-object))

(defclass easygui::cocoa-password-entry-layout-manager (ns:ns-layout-manager)
((last-char-vis-p :accessor last-char-vis-p :initform nil))
(:metaclass ns:+ns-object))

(defclass password-entry-text-view (text-view)
()
(:default-initargs :specifically 'easygui::cocoa-password-entry-text-view))

(objc:defmethod #/initWithFrame: ((self easygui::cocoa-password-entry-text-view) (frame #>NSRect))
(unwind-protect (call-next-method frame)
(#/replaceLayoutManager: (#/textContainer self)
(#/init (#/alloc easygui::cocoa-password-entry-layout-manager)))
(#/setFont: self
(convert-font "Courier" 12))))

(objc:defmethod (#/drawGlyphsForGlyphRange:atPoint: :void) ((self easygui::cocoa-password-entry-layout-manager) (glyph-range #>NSRange) (at-point #>NSPoint))
(let ((glyph-cnt (#/numberOfGlyphs self)))
(let ((hide-until (if (last-char-vis-p self) (1- glyph-cnt) glyph-cnt)))
(dotimes (i hide-until)
(#/replaceGlyphAtIndex:withGlyph: self i 13))))
(call-next-method glyph-range at-point))

(defmethod dialog-item-hidden-text ((view password-entry-text-view))
(let ((text (dialog-item-text view)))
(let ((layout-manager (#/layoutManager (cocoa-ref view))))
(with-output-to-string (strm)
(dotimes (i (1- (length text)))
(format strm "*"))
(format strm "~a" (if (last-char-vis-p layout-manager)
(char text (1- (length text)))
"*"))))))

(defmethod cursor-at-end-of-text-p ((cocoa-self easygui::cocoa-password-entry-text-view))
(awhen (#/selectedRanges cocoa-self)
(when (eq (#/count it) 1)
(awhen (#/rangeValue (#/objectAtIndex: it 0))
(let ((pos (ns:ns-range-location it)))
(let ((length (ns:ns-range-length it)))
(when (eq length 0)
(when (eq pos (#/length (#/string cocoa-self)))
t))))))))

(objc:defmethod (#/keyDown: :void) ((cocoa-self easygui::cocoa-password-entry-text-view) the-event)
(call-next-method the-event)
(labels ((get-keypress (the-event)
(let* ((chars (#/characters the-event))
(str (objc:lisp-string-from-nsstring chars))
(char (char str 0)))
char)))
(handle-keypress-on-view
(easygui::easygui-view-of cocoa-self)
(get-keypress the-event))))

(defmethod handle-keypress-on-view ((view password-entry-text-view) keypress)
(let ((cocoa-self (cocoa-ref view)))
(cond ((or (eq keypress #\rubout)
(not (cursor-at-end-of-text-p cocoa-self)))
(setf (last-char-vis-p (#/layoutManager cocoa-self)) nil))
(t
(setf (last-char-vis-p (#/layoutManager cocoa-self)) t)
(setf (pending-fun cocoa-self)
(alambda ()
(when (eq #'self (pending-fun cocoa-self))
(setf (last-char-vis-p (#/layoutManager cocoa-self)) nil)
(#/setNeedsDisplay: cocoa-self #$YES))))
(schedule-for-event-process
(pending-fun cocoa-self)
(visible-char-time-secs cocoa-self))))))

关于macos - 在 OS X Cocoa 中实现 iOS 密码输入 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15076669/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com