我目前正在开发一款以消息传递为核心功能的iOS应用.消息传递屏幕可能变得非常复杂,特别是试图使它们达到今天的标准.我想知道开发人员用来创建消息传递屏幕的解决方案.是否有一个很好的库开始(我已经检查了JSQMessagesViewController和几乎所有其他
CocoaPod的消息)或者我应该从头开始?
我想要的消息传递屏幕并不是太复杂,我应该能够通过表视图,几个自定义单元格和一些约束来完成它.我正在努力确定我是否应该浪费时间定制一些东西,而我自己可以自己制作.
我该怎么办,自定义现有的库还是从头开始做?
有小费吗?
最佳答案 我意识到这个问题已经存在了一段时间,但由于它没有接受的答案,我将提交我的解决方案.我在下面显示的部分用于显示消息,不包括回复小部件.这应该有助于让人们开始朝着我想做的方向前进.
我使用tableview,一个包含UITextView属性的自定义单元格(但未在storyboard中添加textview,在代码中实例化)以及包含我的SDMessage类实例的表数据数组.
以下是SDMessage类接口文件的内容:
@interface SDMessage : NSObject
@property (nonatomic, strong) NSNumber *message_id;
@property (nonatomic, strong) NSString *message_sender;
@property (nonatomic, strong) NSString *message_content;
@property (nonatomic, strong) NSString *their_id;
@property (nonatomic, strong) NSString *timestamp;
@property (nonatomic, strong) NSDate *dateTime;
@property (nonatomic, strong) NSString *prettyTimestamp;
@property (nonatomic, strong) NSNumber *seen;
@end
我的tableview委托方法如下:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"MsgDetailCell";
MsgDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[MsgDetailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.frame = CGRectMake(2, 2, tableView.frame.size.width - 4, 30);
}
// Since we are creating a new UITextfield with every load, set any existing UITextfield instance to nil
[cell.message removeFromSuperview];
cell.message = nil;
// get the data for this cell (returns self.tableData[indexPath.row])
SDMessage *cellData = [self cellDataForRowAtIndexPath:indexPath];
// get sender id to configure appearance (if we're sending a message it will appear
// on the right side, if we received a message the message will be on the left side of the screen)
long long theirId = [cellData.message_sender longLongValue];
// we have to do this in code so we can set the frame once and avoid cut off text
cell.message = [[UITextView alloc] init];
// set cell text
cell.message.text = cellData.message_content;
// set font and text size (I'm using custom colors here defined in a category)
[cell.message setFont:[UIFont fontWithName:kMessageFont size:kMessageFontSize]];
[cell.message setTextColor:[UIColor gh_messageTextColor]];
// our messages will be a different color than their messages
UIColor *msgColor = (theirId == _myUid) ? [UIColor gh_myMessageBgColor] : [UIColor gh_theirMessageBgColor];
// I want the cell background to be invisible, and only have the
// message background be colored
cell.backgroundColor = [UIColor clearColor];
cell.message.backgroundColor = msgColor;
cell.message.layer.cornerRadius = 10.0;
// make the textview fit the content (kMessageWidth = 220, kMessageBuffer = 15 ... buffer is amount of space from edge of cell)
CGSize newSize = [cell.message sizeThatFits:CGSizeMake(kMessageWidth, MAXFLOAT)];
CGRect newFrame;
// since we are placing the message bubbles justified right or left on the screen
// we determine if this is our message or someone else's message and set the cell
// origin accordingly... (if the sender of this message (e.g. theirId) is us, then take the width
// of the cell, subtract our message width and our buffer and set that x position as our origin.
// this will position messages we send on the right side of the cell, otherwise the other party
// in our conversation sent the message, so our x position will just be whatever the buffer is. (in this case 15)
float originX = (theirId == _myUid) ? cell.frame.size.width - kMessageWidth - kMessageBuffer : kMessageBuffer;
// set our origin at our calculated x-point, and y position of 10
newFrame.origin = CGPointMake(originX, 10);
// set our message width and newly calculated height
newFrame.size = CGSizeMake(fmaxf(newSize.width, kMessageWidth), newSize.height);
// set the frame of our textview and disable scrolling of the textview
cell.message.frame = newFrame;
cell.message.scrollEnabled = NO;
cell.userInteractionEnabled = NO;
// add our textview to our cell
[cell addSubview:cell.message];
return cell;
}
-(CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// we need to make sure our cell is tall enough so we don't cut off our message bubble
MsgDetailCell *cell = (MsgDetailCell*)[self tableView:self.tableview cellForRowAtIndexPath:indexPath];
// get the size of the message for this cell
CGSize newSize = [cell.message sizeThatFits:CGSizeMake(kMessageWidth, MAXFLOAT)];
// get the height of the bubble and add a little buffer of 20
CGFloat textHeight = newSize.height + 20;
// don't make our cell any smaller than 60
textHeight = (textHeight < 60) ? 60 : textHeight;
return textHeight;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SLog(@"didSelectRow: %ld", (long)indexPath.row);
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 0.01;
}
-(UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return [UIView new];
}