IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    helloitworks发表于 2014-05-04 07:29:38
    love 0

    一、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



沪ICP备19023445号-2号
友情链接