我有一个带有WKInterfaceTable固定消息的聊天控制器,每个表行都是一种不同类型的rowController,在WatchKit中附带一个WKInterfaceTable。
每个rowController引用一个在枚举中定义的MessageSource和MessageType。
我的枚举声明看起来不错,但相关字典的实现语法需要一些帮助。
与同一块相关的另一个问题是我的属性的Swift转换。我不确定我是否正确地宣布了它们,因此它们可能会影响相同的块。
我试图修剪尽可能多的代码,因为我知道SO喜欢这样。虽然在不同的函数中有一些引用,但我还包括了保持显式的所需内容。
的OBJ-C
Controller.m或者
typedef enum {
MessageSourceIncoming = 1,
MessageSourceOutgoing = 2
} MessageSource;
typedef enum {
MessageTypeText = 1,
MessageTypeVoice = 2,
MessageTypeImage = 3
} MessageType;
- (void)setupTable {
_messages = [NSMutableArray array];
for (int i = 0; i < rand()%20; i++) {
[_messages addObject:@{@"msg":@[@"Hi", @"OK", @"Nice to meet you", @"Fine"][rand()%4], @"source":@(rand()%2), @"type":@(rand()%3)}];
}
// clear the table rows
[_table removeRowsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, _table.numberOfRows)]];
for (int i = 0; i < _messages.count; i++) {
NSDictionary *messageDic = _messages[i];
[self insertRowForMessage:messageDic];
}
}
- (void)willActivate {
[_table scrollToRowAtIndex:_table.numberOfRows - 1];
if (_shouldSendVoice) {
NSDictionary *messageDic = @{@"source":@(MessageSourceOutgoing), @"type":@(MessageTypeVoice), @"path":_shouldSendVoice};
[_messages addObject:messageDic];
[self insertRowForMessage:messageDic];
_shouldSendVoice = nil;
}
}
答案 0 :(得分:1)
让我们分解一下:
enum MessageSource: Int {
case MessageSourceIncoming = 1
case MessageSourceOutgoing = 2
}
enum MessageType: Int {
case MessageTypeText = 1
case MessageTypeVoice = 2
case MessageTypeImage = 3
}
枚举没有错,但是你需要给它们整数值是一个问题。您不必分配每个值:
enum MessageType: Int {
case MessageTypeText = 1
case MessageTypeVoice
case MessageTypeImage
}
可以正常工作,价值也一样。
var chat = NSDictionary()
var messages = NSMutableArray()
var shouldSendVoice = NSString()
chat
应该是一个Swift词典,但我们没有足够的信息来设置类型,所以我会跳过它。
shouldSendVoice
看起来像布尔值,我们为什么要为它分配NSString
?我不确定你是如何使用那个,所以我不会重命名它,但让我们从它做一个可选的字符串。
messages
应该是一个Swift数组。让我们为Message
创建一个类型:
struct Message {
let message: String?
let source: MessageSource
let type: MessageType
let path: String?
}
var chat = NSDictionary() // let's ignore this
var messages: [Message] = [] // empty swift array of messages
var shouldSendVoice: String? = nil // optional String
现在,让我们重写其余部分:
override func willActivate() {
super.willActivate()
self.table.scrollToRowAtIndex(table.numberOfRows - 1)
// in Obj-C this was checking for nil!, we have to check explicitly in Swift
if let shouldSendVoice = self.shouldSendVoice {
// let's not use Dictionaries for custom objects
let message = Message(message: nil, source: .MessageSourceIncoming, type: .MessageTypeVoice, path: shouldSendVoice)
self.messages.append(message)
self.insertRowForMessage(message)
// I think you don't want new String here, just `nil`
shouldSendVoice = nil
}
}
func setupTable() {
// let's use a saner way to generate randoms
let numMessages = Int(arc4random_uniform(20))
self.messages = (0..<numMessages).map { _ in
let message = // randomize the message
let source = // randomize source
let type = // randomize type
return Message(message: message, source: source, type: type, path: nil)
}
// let's split multiple operations into separate lines to make code more readable
let indicesToRemove = NSIndexSet(indexesInRange:NSMakeRange(0, table.numberOfRows))
self.table.removeRowsAtIndexes(indicesToRemove)
// let's use for-in without using an index
for message in messages {
self.insertRowForMessage(message)
}
}