如何使表视图一次加载所有数据而不是在滚动时更改所述数据?

时间:2016-02-14 01:02:08

标签: ios swift uitableview

我正在创建一个简单的桌面视图应用程序来显示和播放所有iOS系统声音。

我以[ID(Int):Name(String)]的形式将所有的声音和ID都放在一个字典中(我现在意识到这是一个不好的方法),问题是当我加载我的视图时它加载得很好,但如果我向下滚动最初在顶部更改的单元格。从底部滚动到顶部时相同。

例如,视图加载,我可以点击并听到我点击的任何单元格中的各种声音。让我们说第一个单元格是" SMS-Sound1"秒数是" SMS-Sound2"。现在,当我向下滚动到那些单元格不在视图的位置,然后向后滚动到顶部时,它们被命名为不同的东西(仍然来自我的数据字典)。

如何解决此问题,以便加载tableview,然后tableview数据不会更改?

编辑:我认为问题可能是for for循环执行了大约300,000次,但事实并非如此,制作了一个IDS数组,所以它只执行了大约1000次,问题仍然存在< / p>

我的代码:

单元格设置

 override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("soundCell", forIndexPath: indexPath)
        let button = cell.viewWithTag(3) as! UILabel //UILabel in "SoundCell"
        for i: Int in 999..<4100 {
            //Lowest id sound is 1000, highest is 4095
            if (sounds[i] != nil) && loadedSoundStrings.contains(sounds[i]!) == false {
                button.text = sounds[i]
                loadedSoundStrings.append(sounds[i]!)
                cell.tag = i
                break
            }
        }

        return cell
    }

行/部分

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sounds.count
    }

变量:

let sounds =
        [   1000:"new-mail.caf",
            1001:"mail-sent.caf",
            1002:"Voicemail.caf",
            1003:"ReceivedMessage.caf",
            1004:"SentMessag.caf",
            1005:"alarm.caf",
            1006:"low-power.caf",
            1007:"sms-received1.caf",
            1008:"sms-received2.caf",
            1009:"sms-received3.caf",
            1010:"sms-received4.caf",
            1011:"-(SMSReceived_Vibrate)",
            1012:"sms-received1.caf",
            1013:"sms-received5.caf",
            1014:"sms-received6.caf",
            1015:"Voicemail.caf",
            1016:"tweet_sent.caf",
            1020:"Anticipate.caf",
            1021:"Bloom.caf",
            1022:"Calypso.caf",
            1023:"Choo_Choo.caf",
            1024:"Descent.caf",
            1025:"Fanfare.caf",
            1026:"Ladder.caf",
            1027:"Minuet.caf",
            1028:"News_Flash.caf",
            1029:"Noir.caf",
            1030:"Sherwood_Forest.caf",
            1031:"Spell.caf",
            1032:"Suspense.caf",
            1033:"Telegraph.caf",
            1034:"Tiptoes.caf",
            1035:"Typewriters.caf",
            1036:"Update.caf",
            1050:"ussd.caf",
            1051:"SIMToolkitCallDropped.caf",
            1052:"SIMToolkitGeneralBeep.caf",
            1053:"SIMToolkitNegativeACK.caf",
            1054:"SIMToolkitPositiveACK.caf",
            1055:"SIMToolkitSMS.caf",
            1057:"Tink.caf",
            1070:"ct-busy.caf",
            1071:"ct-congestion.caf",
            1072:"ct-path-ack.caf",
            1073:"ct-error.caf",
            1074:"ct-call-waiting.caf",
            1075:"ct-keytone2.caf",
            1100:"lock.caf",
            1101:"unlock.caf",
            1102:"-(FailedUnlock)",
            1103:"Tink.caf",
            1104:"Tock.caf",
            1105:"Tock.caf",
            1106:"beep-beep.caf",
            1107:"RingerChanged.caf",
            1108:"photoShutter.caf",
            1109:"shake.caf",
            1110:"jbl_begin.caf",
            1111:"jbl_confirm.caf",
            1112:"jbl_cancel.caf",
            1113:"begin_record.caf",
            1114:"end_record.caf",
            1115:"jbl_ambiguous.caf",
            1116:"jbl_no_match.caf",
            1117:"begin_video_record.caf",
            1118:"end_video_record.caf",
            1150:"vc~invitation-accepted.caf",
            1151:"vc~ringing.caf",
            1152:"vc~ended.caf",
            1153:"ct-call-waiting.caf",
            1154:"vc~ringing.caf",
            1200:"dtmf-0.caf",
            1201:"dtmf-1.caf",
            1202:"dtmf-2.caf",
            1203:"dtmf-3.caf",
            1204:"dtmf-4.caf",
            1205:"dtmf-5.caf",
            1206:"dtmf-6.caf",
            1207:"dtmf-7.caf",
            1208:"dtmf-8.caf",
            1209:"dtmf-9.caf",
            1210:"dtmf-star.caf",
            1211:"dtmf-pound.caf",
            1254:"long_low_short_high.caf",
            1255:"short_double_high.caf",
            1256:"short_low_high.caf",
            1257:"short_double_low.caf",
            1258:"short_double_low.caf",
            1259:"middle_9_short_double_low.caf",
            1300:"Voicemail.caf",
            1301:"ReceivedMessage.caf",
            1302:"new-mail.caf",
            1303:"mail-sent.caf",
            1304:"alarm.caf",
            1305:"lock.caf",
            1306:"Tock.caf",
            1307:"sms-received1.caf",
            1308:"sms-received2.caf",
            1309:"sms-received3.caf",
            1310:"sms-received4.caf",
            1311:"-(SMSReceived_Vibrate)",
            1312:"sms-received1.caf",
            1313:"sms-received5.caf",
            1314:"sms-received6.caf",
            1315:"Voicemail.caf",
            1320:"Anticipate.caf",
            1321:"Bloom.caf",
            1322:"Calypso.caf",
            1323:"Choo_Choo.caf",
            1324:"Descent.caf",
            1325:"Fanfare.caf",
            1326:"Ladder.caf",
            1327:"Minuet.caf",
            1328:"News_Flash.caf",
            1329:"Noir.caf",
            1330:"Sherwood_Forest.caf",
            1331:"Spell.caf",
            1332:"Suspense.caf",
            1333:"Telegraph.caf",
            1334:"Tiptoes.caf",
            1335:"Typewriters.caf",
            1336:"Update.caf",
            1350:"-(RingerVibeChanged)",
            1351:"-(SilentVibeChanged)",
            4095:"-(Vibrate)"]

var loadedSoundStrings = [String]()

3 个答案:

答案 0 :(得分:0)

如果我正确理解你的代码,那你就是错误的做法。你有一个加载一次的声音字典。 cellForRowAtIndexPath函数应返回一个tableViewCell,其中包含一个声音的详细信息。

UITableView会自动丢弃屏幕外的单元格以节省内存,并将其重新用于新显示的单元格。这就是你致电dequeueReusableCellWithIdentifier的原因。因此,您应该这样做:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("soundCell", forIndexPath: indexPath)
        let button = cell.viewWithTag(3) as! UILabel //UILabel in "SoundCell"
        //Lowest id sound is 1000, highest is 4095
        let i = indexPath.row + 1000
        button.text = sounds[i]
        cell.tag = i
        return cell
    }

由于您正在对声音编号范围进行硬编码,所以我也做了同样的事情。

答案 1 :(得分:0)

表视图最适合数组,因为数组具有已定义的顺序,您可以快速访问给定元素; cellForRowAtIndexPath中的for循环很少是好事。

但是,你有几个问题,因为你的声音标识符不是从0开始,你不能使用标识符作为数组的直接索引,但标识符也不是顺序的,所以你可以甚至使用简单的偏移量(为行号添加一个常量值)。

我认为最好的解决方案不是像你的字典一样直接依赖内在类型,而是为每个声音创建一个结构并存储它们的数组。像这样:

class MyViewController: UIViewController, UITableViewDelegate, UITableViewDatasource

   struct Sound {
    var id:Int
    var fileName:String
   }

   var sounds=[Sound]()

   func loadSounds() {
       let soundsDict =
        [1000:"new-mail.caf",
        1001:"mail-sent.caf",
        1002:"Voicemail.caf",
        1003:"ReceivedMessage.caf",
        1004:"SentMessag.caf",
        1005:"alarm.caf",
        1006:"low-power.caf",
        1007:"sms-received1.caf",
        1008:"sms-received2.caf",
        ...
        ]

        for (id,fileName) in soundsDict {
            self.sounds.append(Sound(id: id, fileName: fileName))
        } 
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("soundCell", forIndexPath: indexPath)
        let button = cell.viewWithTag(3) as! UILabel //UILabel in "SoundCell"

        button.text=self.sounds[indexPath.row].fileName  

        return cell
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.sounds.count
    }    
}

答案 2 :(得分:0)

当您实际想要仅为加载的行实例化声音时,您正在实例化每一行的所有声音。要修复订单问题,请更改您的订单      cellForRowAtIdexPath

到此:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
  let cell = tableView.dequeueReusableCellWithIdentifier("soundCell", forIndexPath: indexPath)
  let button = cell.viewWithTag(3) as! UILabel //UILabel in "SoundCell"
  button.text = sounds[i]
  cell.tag = indexPath.row
  return cell
}

由于您将NumberOfRowsInSection设置为sounds.count,因此每个单元格会发出1个声音。对于您拥有的每个声音,都会调用行的单元格。