首页 > 白话Cocoa > Safari浏览器地址栏下拉列表的实现

Safari浏览器地址栏下拉列表的实现

一、Safari浏览器地址栏下拉列表

642f2ac8db60e55bc6f4d3fb3034d2ad


如上图所示,Safari浏览器地址栏输入文字时,下方会自动弹出一个类似于菜单的下拉列表,用于展示关联的内容。
他是怎么实现的呢?
首先可以肯定的,这个下拉列表不是使用菜单做的,因为菜单会有焦点的问题,弹出菜单会抢占输入的焦点,同时移动safari的时候,这个下拉列表是跟着safari移动的,而菜单是会消失的。
这个下拉列表是safari浏览器的子窗口,子窗口不会抢占输入焦点,同时也可以随着主窗口一块移动。
窗口的默认样式是上方两个角是直角,下方两个角是圆角,而这个子窗口四个角都是圆角,所以我们还要定制子窗口的四个角为圆角。
下拉列表的内容展示就简单了,我们可以用table view来展示,同时捕获table view的鼠标事件来实现选择的高亮以及鼠标的点击事件。

二、写了一个类似的demo:

ded64be747e6b7a437bf1b1e51de6317

1、用NSSearchFiled来模拟地址栏

NSSearchFiled的delegate函数controlTextDidChange:可以捕获NSSearchFiled内容的改变

- (void)controlTextDidChange: (NSNotification *)aNotification
{
    NSString *searchString = [self.searchField stringValue];
}

NSSearchFiled的delegate函数control:textView:doCommandBySelector:,可以捕获键盘的命令操作,比如左移,右移,回车事件。如果返回TRUE,那么delegate负责处理键盘的事件,如果返回NO,那么由父类默认处理。

2、用child window跟table view来模拟弹出的下拉列表,里面用到的几个主要的类介绍如下:

* SYXMenuWindowController类实现菜单窗口的主体功能,包括窗口的弹出,窗口的关闭,table view的展示, 实现table view鼠标事件的delegate函数等。

* BorderlessWindow这个类是NSWindow类的派生类,主要是产生一个没有边框的窗体,并将窗体contentView的superView设成RoundWindowFrameView(RoundWindowFrameView重定义了View的drawRect可以将view设置成四个角都是圆形)

* DetectingTableView这个类是NSTableView的派生类,用于监听table view上的鼠标进入、移出、移动事件以及点击事件。我们监听到鼠标进入table view以及在table view上移动,通过调用selectRowIndexes的方式来改变选择行的颜色。鼠标移出table view,通过调用deselectAll来取消选择。另外,当我们焦点在SearchFiled,键盘按下方向键的向下时,也是通过selectedRow获取table view当前选择的行,并且通过selectRowIndexes函数选择当前选择行的下一行来实现向下键选择下一行的操作。

源代码:https://github.com/helloitworks/MenuWindow

(转载本站文章请注明出处 www.helloitworks.com ,请勿用于任何商业用途)

分类: 白话Cocoa 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.