- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
这里的问题是我在我的 TableView 中得到了重复项,我知道为什么,但我不知道如何修复它并实现一个不同的系统。
我的应用程序是一个博客阅读器,它使用 PHP 从 MYSQL 数据库读取数据并将 JSON 发送到我的 Swift 应用程序。我的 TableView 有两个部分,一个用于数据库中的所有对象,第二个部分用于当我单击单元格上的关注按钮时,基本上将对象从 mainArray 移动到 followedArray。每个部分都使用一个数组,例如,我将所有对象从 mainArray 移动到 followedArray 并更新表,我在 mainArray 中再次获取所有这些对象,显然是因为 mainarray 是空的,代码只是在做它的工作。
那么我该如何实现一个更好的系统,以便当用户将对象从一个部分移动到另一个部分(或从 mainArray 到 followedArray)时,mainArray 不会重新填充它在 followedArray 中的相同对象。
这是我使用的代码。
MainController.swift - Tableview 所在的类
var mainArray = [Blog]()
var followedArray = [Blog]()
// Title for Header
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if !(searchController.isActive && searchController.searchBar.text != "") {
if section == 0 {
return "Followed Blogs"
}
else {
return "All Blogs"
}
}
return "Filtered Blogs"
}
// Number of Rows in Section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !(searchController.isActive && searchController.searchBar.text != "") {
if section == 0 {
return followedArray.count
}
else if (section == 1) {
return mainArray.count
}
}
return filteredArray.count
}
// CellForRowAt indexPath
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let CellIdentifier = "Cell"
var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! CustomCell
if cell != cell {
cell = CustomCell(style: UITableViewCellStyle.default, reuseIdentifier: CellIdentifier)
}
// Configuring the cell
var blogObject: Blog
if !(searchController.isActive && searchController.searchBar.text != "") {
if indexPath.section == 0 {
blogObject = followedArray[indexPath.row]
cell.populateCell(blogObject, isFollowed: true, indexPath: indexPath, parentView: self)
}
else if indexPath.section == 1 {
blogObject = mainArray[indexPath.row]
cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
}
}
else {
blogObject = filteredArray[indexPath.row]
cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
}
return cell
}
// Follow Button
@IBAction func followButtonClick(_ sender: UIButton!) {
// Adding row to tag
let buttonPosition = (sender as AnyObject).convert(CGPoint.zero, to: self.myTableView)
if let indexPath = self.myTableView.indexPathForRow(at: buttonPosition) {
// Showing Status Labels
let cell = self.myTableView.cellForRow(at: indexPath) as! CustomCell
cell.firstStatusLabel.isHidden = false
cell.secondStatusLabel.isHidden = false
// Change Follow to Following
(sender as UIButton).setImage(UIImage(named: "follow.png")!, for: .normal)
cell.followButton.isHidden = true
cell.followedButton.isHidden = false
// Checking wether to import from mainArray or filteredArray to followedArray
if !(searchController.isActive && searchController.searchBar.text != "") {
self.myTableView.beginUpdates()
// ----- Inserting Cell to followedArray -----
followedArray.insert(mainArray[indexPath.row], at: 0)
myTableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .fade)
// ----- Removing Cell from mainArray -----
mainArray.remove(at: indexPath.row)
let rowToRemove = indexPath.row
self.myTableView.deleteRows(at: [IndexPath(row: rowToRemove, section: 1)], with: .fade)
self.myTableView.endUpdates()
myTableView.reloadData()
// After Updating Table, Save the Archived to UserDefaults
saveUserDefaults()
}
else {
self.myTableView.beginUpdates()
// ----- Inserting Cell to followedArray -----
let blogObject: Blog = filteredArray[indexPath.row]
let indexOfObjectInArray = mainArray.index(of: blogObject)
followedArray.insert(blogObject, at: 0)
// ----- Removing Cell from filteredArray -----
filteredArray.remove(at: indexPath.row)
mainArray.remove(at: indexOfObjectInArray!)
let rowToRemove = indexPath.row
self.myTableView.deleteRows(at: [IndexPath(row: rowToRemove, section: 0)], with: .fade)
self.myTableView.endUpdates()
myTableView.reloadData()
// After Updating Table, Save the Archived to UserDefaults
saveUserDefaults()
}
}
}
// Retrieving Data from Server
func retrieveDataFromServer() {
let getDataURL = "http://example.com/receiving.php"
let url: NSURL = NSURL(string: getDataURL)!
do {
let data: Data = try Data(contentsOf: url as URL)
let jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray
// Looping through jsonArray
for jsonObject in jsonArray {
if let blog = Blog.createGame(from: jsonObject as AnyObject) {
mainArray.append(blog)
}
}
}
catch {
print("Error: (Retrieving Data)")
}
myTableView.reloadData()
}
Blog.swift - 处理我也使用 NSCoder 的博客对象
import UIKit
class Blog: NSObject, NSCoding {
var blogName: String!
var blogStatus1: String!
var blogStatus2: String!
var blogURL: String!
var blogID: String!
var blogType: String!
var blogDate: String!
var blogPop: String!
static func createBlog(from jsonObject: AnyObject) -> Blog? {
guard let bID: String = jsonObject.object(forKey: "id") as? String,
let bName: String = jsonObject.object(forKey: "blogName") as? String,
let bStatus1: String = jsonObject.object(forKey: "blogStatus1") as? String,
let bStatus2: String = jsonObject.object(forKey: "blogStatus2") as? String,
let bURL: String = jsonObject.object(forKey: "blogURL") as? String,
let bType: String = jsonObject.object(forKey: "blogType") as? String,
let bDate: String = jsonObject.object(forKey: "blogDate") as? String,
let bPop: String = jsonObject.object(forKey: "blogPop") as? String
else {
print("Error: (Creating Blog Object)")
return nil
}
let blog = Blog()
blog.blogName = bName
blog.blogStatus1 = bStatus1
blog.blogStatus2 = bStatus2
blog.blogURL = bURL
blog.blogID = bID
blog.blogType = bType
blog.blogDate = bDate
blog.blogPop = bPop
return blog
}
convenience required init?(coder aDecoder: NSCoder) {
self.init ()
self.blogName = aDecoder.decodeObject(forKey: "blogName") as! String
self.blogStatus1 = aDecoder.decodeObject(forKey: "blogStatus1") as! String
self.blogStatus2 = aDecoder.decodeObject(forKey: "blogStatus2") as! String
self.blogURL = aDecoder.decodeObject(forKey: "blogURL") as! String
self.blogID = aDecoder.decodeObject(forKey: "blogID") as! String
self.blogType = aDecoder.decodeObject(forKey: "blogType") as! String
self.blogDate = aDecoder.decodeObject(forKey: "blogDate") as! String
self.blogPop = aDecoder.decodeObject(forKey: "blogPop") as! String
}
func encode(with aCoder: NSCoder) {
aCoder.encode(blogName, forKey: "blogName")
aCoder.encode(blogStatus1, forKey: "blogStatus1")
aCoder.encode(blogStatus2, forKey: "blogStatus2")
aCoder.encode(blogURL, forKey: "blogURL")
aCoder.encode(blogID, forKey: "blogID")
aCoder.encode(blogType, forKey: "blogType")
aCoder.encode(blogDate, forKey: "blogDate")
aCoder.encode(blogPop, forKey: "blogPop")
}
}
在重新填充 mainArray 之前是否有一种方法可以检查 followedArray 中有什么以及丢失或添加到数据库中的任何内容以导入而不创建重复项,因为将添加新博客并且用户将跨部分传输博客所以这是一个我遇到的主要问题。
感谢您的帮助,因为我仍在学习 Swift,谢谢。
最佳答案
我建议将应在后续类别中的博客的唯一标识符保存到一个数组中,并在每次重新加载 tableView 时,将适当的单元格移动到正确的部分。
您似乎在使用 UserDefaults但没有对它们进行修改。使用我的方法,唯一需要保存到 UserDefaults 和从中加载的数组是关注博客的列表。其余的默认为主列表,即使出现新博客也是如此。
你还需要一个数组:
var mainArray = [Blog]()
var followedArray = [Blog]()
var followedIdentifiers = [String]()
或者标识符将属于的任何数据类型
您也可以使用 Set
因为您不希望 followedIdentifiers 中有重复项
var followedIdentifiers = Set<String>()
以下是对代码相关部分的修改(我的更改标记为 <----
):
// Checking whether to import from mainArray or filteredArray to followedArray
if !(searchController.isActive && searchController.searchBar.text != "") {
self.myTableView.beginUpdates()
// Save identifier into followedIdentifier array <--------------
self.followedIdentifiers.insert(mainArray[indexPath.row].blogID)
// ----- Inserting Cell to followedArray -----
followedArray.insert(mainArray[indexPath.row], at: 0)
myTableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .fade)
// ----- Removing Cell from mainArray -----
mainArray.remove(at: indexPath.row)
let rowToRemove = indexPath.row
self.myTableView.deleteRows(at: [IndexPath(row: rowToRemove, section: 1)], with: .fade)
self.myTableView.endUpdates()
myTableView.reloadData()
// After Updating Table, Save the Archived to UserDefaults
saveUserDefaults()
} else {
self.myTableView.beginUpdates()
// Remove identifier into followedIdentifier array <------------
self.followedIdentifiers.remove(followedArray[indexPath.row].blogID)
// ----- Inserting Cell to followedArray -----
let blogObject: Blog = filteredArray[indexPath.row]
let indexOfObjectInArray = mainArray.index(of: blogObject)
followedArray.insert(blogObject, at: 0)
// ----- Removing Cell from filteredArray -----
filteredArray.remove(at: indexPath.row)
mainArray.remove(at: indexOfObjectInArray!)
let rowToRemove = indexPath.row
self.myTableView.deleteRows(at: [IndexPath(row: rowToRemove, section: 0)], with: .fade)
self.myTableView.endUpdates()
myTableView.reloadData()
// After Updating Table, Save the Archived to UserDefaults
saveUserDefaults()
}
// Retrieving Data from Server
func retrieveDataFromServer() {
let getDataURL = "http://example.com/receiving.php"
let url: NSURL = NSURL(string: getDataURL)!
do {
let data: Data = try Data(contentsOf: url as URL)
let jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray
// Clear the arrays <-------------
self.followedArray = [Blog]()
self.mainArray = [Blog()]
// Looping through jsonArray
for jsonObject in jsonArray {
if let blog = Blog.createBlog(from: jsonObject as AnyObject) {
// Check if identifiers match <------------
if followedIdentifiers.contains(blog.blogID) {
self.followedArray.append(blog)
} else {
self.mainArray.append(blog)
}
}
}
} catch {
print("Error: (Retrieving Data)")
}
myTableView.reloadData()
}
为了让它跨 session 工作,你必须在你的saveUserDefaults()
中有类似的东西
UserDefaults.standard.setValue(Array(self.followedIdentifiers), forKey: "someName")
这是你从 UserDefaults 加载的地方
self.followedIdentifiers = Set(UserDefaults.standard.stringArray(forKey: "someName"))
关于ios - Swift:如何从我的 TableView 中删除重复项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44575422/
我正在对 tableView 是否呈现单元格进行单元测试。 我发现 tableView.cellForRow(at:) 返回 nil,而 tableView.dataSource?tableView(
我有 Tableview 用于显示客户下的食品订单。其中包含水平 UIStackview。在 UIStackView UIStackview 中很少有一/两行标签和一个用于显示订单项的UITableV
我有 Viewcontroller,我在其中设置了 ScrollView 。在 scrollview 中,我有一个 tableview,它位于 Container 中,就在容器下方,当我将 table
我想在滚动时让我的第一个单元格始终位于 tableview 的顶部。 任何帮助都是可观的。提前致谢... 最佳答案 这是为 UITableView 创建标题 View 的方法 - (UIView *)
在我的应用程序中,我点击一行,它会在其下方展开另一行。我想生成一种随机颜色,当我单击一行时,行背景会变成该颜色,而它下面的展开行会变成相同的颜色。如何让行生成相同的随机颜色? 我创建了一个函数来生成随
我正在为这个问题苦苦挣扎,所以我需要你的帮助。基本上我已经编写了一个复杂的 TableView Controller (使用 NSFetchedResults 协议(protocol)等)并且已经在我
我正在使用 JavaFx 2.2。我遇到了一个问题,我无法在 TableView 列中放置不同的组件。例如我有两列 1) 回答 2) 答案类型 如果 AnswerType 包含“Multiple Ch
试图弄清楚如何在 javafx 2 中禁用表列的重新排序? 最佳答案 这是解决方案: tblView.getColumns().addListener(new ListChangeListener()
我一直在寻找有关将数据刷新到 tableview 的信息。我试图直接修改模型,但我遇到了一个错误。我修改了模型,但表格没有刷新,只有当我移动一列时,表格才会显示修改后的值。 为了给你展示一个例子(13
给定一个TableView,我需要检测单元格上的双击。 tableView.setOnMouseClicked(new EventHandler() { @Override publi
我成功创建了一个 TableView,其中将特定列分配给了数据模型类。该程序可以将 csv 文件解析为其中并在表中正确显示所有内容。在此阶段,滚动不是问题。 然后我想选择特定行并将它们发送到另一个表。
我尝试了所有方法来用数据填充 TableView。下一个代码在表中插入一个新行,但数据没有出现在表中。我试图为此找到解释,但没有成功。 请帮忙。我不知道怎么了。 在 controller.java 中
我尝试了所有方法来用数据填充 TableView。下一个代码在表中插入一个新行,但数据没有出现在表中。我试图为此找到解释,但没有成功。 请帮忙。我不知道怎么了。 在 controller.java 中
我有一个通过 Tableview 显示玩家的应用程序。用户可以“添加”一个新玩家并输入他的姓名、高度、体重、图片等...保存后将被添加到 Tableview 中。他们还可以点击每个玩家,然后将他们带到
对于大学,我必须编写一个小应用程序,其想法是创建一个小公式集合。这个概念是有一个类别列表,选择类别后您会收到一个公式列表。选择所需的公式后,您将看到公式计算器的 View 。 我正在努力获得第一个UI
如果我只加载一个 TableView ,我的 View 中必须有两个 TableView ,它工作正常。但是当我尝试使用下面的方法加载两个表格 View 时,它给出了以下异常。 未捕获异常“NSRan
我是 JavaFx 的新手,我正在尝试创建一个 TableView ,而 fxml 是使用场景生成器创建的。如果我运行该程序,该表不会获取值。我发现这个问题在某种程度上符合我的要求( javaFX 2
是否可以对 tableView 进行反向排序?我搜索了很多解决方案,但没有任何效果。 效果就像whatsapp聊天。 一个普通的tableView是: ---------- label 1 -----
我有一个有趣的问题。我有两个 TableView ,一个在另一个里面。我有一个结构,我想用它来将数据添加到我的 TableView 中。该结构有 2 个字符串项和另一个具有 3 个字符串项的结构的数组
我正在使用的方法 func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath
我是一名优秀的程序员,十分优秀!