简体   繁体   English

可观察对象和UItableview可见单元格

[英]observables and the UItableview visible cells

I am writing an IOS chat app. 我正在编写一个IOS聊天应用程序。 I have a tableview where each cell contains a textbox, upon loading each cell I subscribe to a chat channel on pubnub.com. 我有一个tableview,其中每个单元格包含一个文本框,加载每个单元格后,我订阅了pubnub.com上的聊天频道。 I have an observable in the viewdidLoad watching for incoming messages. 我在viewdidLoad中有一个可观察的入口消息。 The object receieved from the observable contains the channel name and the message text and date. 从可观察对象接收到的对象包含通道名称以及消息文本和日期。 I want to display messages to their appropriate cells. 我想向其适当的单元格显示消息。 I'm not sure where to capture a fully loaded cell when its in view and subscribe to the channel. 我不确定在查看并订阅频道时在哪里捕获满载的单元。 Then in the observable how do I compare the channel name to the cell currently in view on the screen? 然后,在可观察的位置,如何将通道名称与屏幕上当前正在查看的单元格进行比较? I tried the isVisible but I'm getting more than whats visible on the screen. 我尝试了isVisible,但获得的不仅仅是屏幕上可见的内容。 The thing is I want to only show messages to cells that are currenty in view, kind of how vine starts to playa video when the user has stopped on that cell even if they dont click it.. 问题是我只想向当前显示的单元格显示消息,这是一种即使用户不单击该视频,当用户停止在该单元格上时,vine仍如何开始播放视频的方式。

See code below 见下面的代码

- (void)viewDidLoad
{
    [super viewDidLoad];

    appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    self.messages = [NSMutableDictionary dictionary];
    self.configuration = [PNConfiguration defaultConfiguration];

    [self load_DEMO_DATA];
    [self setClient];
    [self connectToServer];

    //Observable
    [[PNObservationCenter defaultCenter] addMessageReceiveObserver:self
                                                         withBlock:^(PNMessage *message) {

        NSDateFormatter *dateFormatter = [NSDateFormatter new];
        dateFormatter.dateFormat = @"HH:mm:ss MM/dd/yy";
        PNChannel *channel = message.channel;

        NSString *messages = [self.messages valueForKey:channel.name];
        if (messages == nil) {messages = @"";}
        messages = [messages stringByAppendingFormat:@"<%@> %@\n",[dateFormatter stringFromDate:message.receiveDate.date],message.message];

        //Get TextBox & Set Caption                                                                                    
        UITextView *caption = (UITextView *)[[(UITableViewCell *)[(UITableView    *)self.tableView cellForRowAtIndexPath:CurrentIndexPath] contentView] viewWithTag:105];

        caption.text = [NSString stringWithFormat:@"%@%@", caption.text, messages];
        [caption scrollRangeToVisible:NSMakeRange([caption.text length], 0)];                         
    }];

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"TimelinePostCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell==nil)
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

    // Configure the cell...
    NSDictionary *post = [posts objectAtIndex:indexPath.item];
    NSDictionary *user = [post objectForKey:@"user"];

    //Set Current Channel
    self.currentChannel = [PNChannel channelWithName:[post objectForKey:@"channelName"]      shouldObservePresence:YES];

    //Subscribe to Chat
    [self subscribeToChannel:self.currentChannel.name];
    self.currentPost = post;

    //Get Channel History
    [self ChannelHistory];

    return cell;
}

Well, first of all, -tableView:cellForRowAtIndexPath: shouldn't be used to initiate any time consuming operations. 好吧,首先, -tableView:cellForRowAtIndexPath:不应该用于启动任何耗时的操作。 To keep high performance, you should return prepared UITableViewCell from that method less then in 160ms or you will see "lag" . 为了保持高性能,您应该在不到160ms的时间内从该方法返回准备好的UITableViewCell ,否则将看到“ lag” This method will be called few times right after table has been shown (as many as you have cells with values). 在显示表格后,此方法将被调用几次(与具有值的单元格一样多)。

You should use –scrollViewDidEndDragging:willDecelerate: (with decelerate NO ) and –scrollViewDidEndDecelerating: as appropriate place and time when you should initiate subscriptions to the channel and any other manipulation with PubNub client. 当您应该启动频道的订阅以及使用PubNub客户端进行任何其他操作时,应使用–scrollViewDidEndDragging:willDecelerate:带有减速 NO )和–scrollViewDidEndDecelerating:作为适当的时间和地点

You can subscribe on all channels at once - it will be less network overhead than subscribing for every single channel one-by-one. 您可以一次在所有频道上进行订阅-与为每个频道进行一对一订阅相比,这将减少网络开销。 If you want to preserve resources and keep pricing low by keeping client subscribed on few channels, than you should use same methods to unsubscribe from previous channels (same as were suggested to detect current cell and store current channel and so on). 如果您想通过让客户在几个频道上进行订阅来节省资源并保持较低的价格,则应该使用相同的方法来退订先前的频道(与建议的方法相同,即检测当前单元格并存储当前频道,依此类推)。

Also just suggestion about how you feed cell with model: move model processing inside custom cell class (there is no reason for controller to know something about structure of cell's views and which data should be shown there). 也只是建议您如何使用模型填充单元格:在自定义单元格类中移动模型处理(控制器没有理由了解单元格视图的结构以及应在此处显示哪些数据)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM