使用NSOutlineView和MouseTracking 要做一个IM当然首要就是能够管理用户了,所以,要求具有显示分组用户的需求,就像Adium和iChat。我开始想用NSTableView,但是这个类不具有分组的功能,后来看到了NSOutlineView就解决了分组的问题。 分组问题解决方案: 要使用分组功能,就必须为NSOutlineView实现datasource和delegate的一些函数: outlineView:child:ofItem:、outlineView:numberOfChildrenOfItem:和outlineView:objectValueForTableColumn:byItem:告诉了NSOutlineView它的每行每列应该显示怎样的数据。如果你想要编辑某一行的内容,比如说你想要编辑IM中某个好友的昵称,就可以实现outlineView:setObjectValue:forTableColumn:byItem:这个方法。 只要上述方法能够正确返回你自己定义的结构,那么就可以正确分组显示用户了。 现在的问题是,你不能显示头像,不能显示状态,只能显示用户名,因为现在NSOutlineView默认的显示单元是NSTextfieldCell,如果想显示更为丰富的内容,那么你就要定义自己的NSCell子类。 自定义行的内容解决方案 定义自己的NSCell子类,比如myCell。 在myCell中实现方法drawInteriorWithFrame:inView:,这个方法定义了NSOutlineView中某行的显示内容,你可以在这个方法中绘制上用户的头像,用户的状态,或者用自定义的信息。这个方法一定要实现,否则还是只能显示文本。 调用setDataCell:或者在Interface Builder中直接指定NSOutlineView的显示单元为myCell。 又有问题了myCell怎么知道用户的状态、头像呢? 还记得前面实现的outlineView:objectValueForTableColumn:方法吗,这个方法的返回值是一个指针(id),我们可以返回任何值,一般只需要返回NSString就可以了,因为这个返回值的接收方就是NSOutlineView的显示单元,我们想要让myCell知道用户的头像等信息,我的解决方法: 就是将这些信息全部包含到outlineView:objectValueForTableColumn:的返回值中,定义一个自己的数据结构,比如FriendInfo类。记住FriendInfo类一定要实现方法copyWithZone:方法,否则myCell无法接收。 在myCell中调用方法objectValue:函数,得到之前传递过来的FriendInfo指针,这样,我们就可以在myCell中绘制想要的信息了。 我们现在已经很好实现了用户列表的功能了,不过似乎还是没有iChat中那么明显的分组功能,想要明显一些,那么实现这个方法吧,还是NSOutlineView的degelate方法:outlineView:isGroupItem:,这样看起来就比较像iChat了。效果参见下面图片: ==================== 上面说了怎么去建立一个看起来不错的用户列表,下面说说迷人的按钮是怎么做出来的,就像lumaqq中这个迷人的+号按钮,这里就用到了我前面提到的MouseTracking 其实说起来,这个+按钮就是两张图片,当没有事请发生的时候显示一张,当鼠标进入 图片区域的时候显示另一张,鼠标在这个图片区域按下就相应一些事件,很多mac下面的程序都用这个方法去实现按钮,确实可以做的很漂亮,也很方便。要想实现这个功能,我们要做下面几步: 定义一个跟踪区域,使用初始化函数initWithRect:options:owner:userInfo:定义一个NSTrackingArea跟踪区域。 把这个区域使用addTrackingArea:方法添加到某一个NSView对象中。 有必要的话,实现updateTrackingAreas方法来更新这个区域,一般在窗口大小改变的时候会调用这个方法。 调用mouseEntered:、mouseMoved:、mouseExited:等方法来响应鼠标事件,实现按钮的模拟。 还可以调用cursorUpdate:方法来改变鼠标的外观。 通过这些,我们就可以非常好的做出漂亮的按钮了。
-
Pages
-
Tags
-
Recent Posts
-
Recent Comments