Swift 3:Segue 并将数据从一个 class 传递到另一个
Swift 3: Segue and pass in data from one class to another
我有一个名为 HomeController
的简单 UICollectionViewController,它有一堆单元格。这些细胞有自己的 class,称为 PostCell
。我还有一个 NSObject class,它保存每个 Post
的所有数据(这些 post 是我的单元格)。在我的 PostCell 中,我有一个名为 profileSegueContainer
的 UIView
。当我点击这个 UIView 时,我想转到一个新的控制器。我可以使用 presentViewController 方法实现此目的,但我还想传递特定 post 的信息。例如,如果我点击一个 uid
为“1234”的单元格,我不仅希望能够连接到新控制器,而且还能将此 uid 传递给它。当然,如果我点击下一个单元格并且该单元格的 post.uid
是“4567”,那么我也想在我继续时传递它。我希望这是有道理的……我希望它的工作方式类似于 Instagram 的 "tapped on a user to get to their profile" 功能。我希望这是有道理的。任何帮助将不胜感激,当然,我会标记为答案。谢谢你。所有相关代码如下:
class Post: NSObject {
var author: String?
var avatar_image_url: String?
var likes: Int?
var postImageUrl: String?
var uid: String?
var post_id: String?
var hashtags: [String]?
}
class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var postCell: PostCell?
var userProfileController: UserProfileController?
var posts = [Post]()
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView?.backgroundColor = grayBackgroundColor
self.collectionView?.register(PostCell.self, forCellWithReuseIdentifier: reuseIdentifier)
self.collectionView?.contentInset = UIEdgeInsetsMake(16, 0, 16, 0)
self.collectionView?.alwaysBounceVertical = true
self.collectionView?.showsVerticalScrollIndicator = false
setupNavigationBarBranding()
checkIfUserIsLoggedIn()
fetchPosts()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let frameWidth = self.view.frame.size.width
let width = frameWidth - (16 + 16)
let height = frameWidth - (16 / 9) + 50 + 50
return CGSize(width: width, height: height)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PostCell
cell.homeController = self
cell.post = posts[indexPath.item]
userProfileController?.post = posts[indexPath.item]
return cell
}
}
class PostCell: BaseCell {
var homeController: HomeController?
var userProfileController: UserProfileController?
var post: Post? {
didSet {
if let postDisplayName = post?.author {
displayName.text = postDisplayName
}
if let postImageUrl = post?.postImageUrl {
postImage.loadImageUsingCacheWithUrlString(urlString: postImageUrl)
}
if let postProfileImage = post?.avatar_image_url {
profileImage.loadImageUsingCacheWithUrlString(urlString: postProfileImage)
}
}
}
lazy var profileSegueContainer: UIView = {
let view = UIView()
view.isUserInteractionEnabled = true
return view
}()
func handleProfileSegue() {
let userProfile = UserProfileController()
let navigationUserProfile = UINavigationController(rootViewController: userProfile)
homeController?.present(navigationUserProfile, animated: true, completion: nil)
}
override func setupViews() {
super.setupViews()
let tap = UITapGestureRecognizer(target: self, action: #selector(handleProfileSegue))
profileSegueContainer.addGestureRecognizer(tap)
addSubview(profileSegueContainer)
_ = profileSegueContainer.anchor(profileImage.topAnchor, left: profileImage.leftAnchor, bottom: profileImage.bottomAnchor, right: displayName.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
}
在视图控制器的上下文中,Segue 具有非常具体的含义。您可能想改用短语 "push another view controller"。
首先,UINavigationController
通常只在一个场景中使用一次——它是跟踪一堆子视图控制器的视图控制器。您只创建其中一个,并且您可能希望将 HomeController
设置为导航控制器的 rootViewController
。
然后当用户点击视图时,您应该将其转发给您将添加到 HomeController 的方法;这将创建您的自定义 UserProfile
class,使用所需的数据配置它,然后调用:navigationController?.pushViewController(userProfile, animating: true)
有很多优秀的教程可以向您展示这一切是如何工作的。
我有一个名为 HomeController
的简单 UICollectionViewController,它有一堆单元格。这些细胞有自己的 class,称为 PostCell
。我还有一个 NSObject class,它保存每个 Post
的所有数据(这些 post 是我的单元格)。在我的 PostCell 中,我有一个名为 profileSegueContainer
的 UIView
。当我点击这个 UIView 时,我想转到一个新的控制器。我可以使用 presentViewController 方法实现此目的,但我还想传递特定 post 的信息。例如,如果我点击一个 uid
为“1234”的单元格,我不仅希望能够连接到新控制器,而且还能将此 uid 传递给它。当然,如果我点击下一个单元格并且该单元格的 post.uid
是“4567”,那么我也想在我继续时传递它。我希望这是有道理的……我希望它的工作方式类似于 Instagram 的 "tapped on a user to get to their profile" 功能。我希望这是有道理的。任何帮助将不胜感激,当然,我会标记为答案。谢谢你。所有相关代码如下:
class Post: NSObject {
var author: String?
var avatar_image_url: String?
var likes: Int?
var postImageUrl: String?
var uid: String?
var post_id: String?
var hashtags: [String]?
}
class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
var postCell: PostCell?
var userProfileController: UserProfileController?
var posts = [Post]()
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView?.backgroundColor = grayBackgroundColor
self.collectionView?.register(PostCell.self, forCellWithReuseIdentifier: reuseIdentifier)
self.collectionView?.contentInset = UIEdgeInsetsMake(16, 0, 16, 0)
self.collectionView?.alwaysBounceVertical = true
self.collectionView?.showsVerticalScrollIndicator = false
setupNavigationBarBranding()
checkIfUserIsLoggedIn()
fetchPosts()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let frameWidth = self.view.frame.size.width
let width = frameWidth - (16 + 16)
let height = frameWidth - (16 / 9) + 50 + 50
return CGSize(width: width, height: height)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return posts.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! PostCell
cell.homeController = self
cell.post = posts[indexPath.item]
userProfileController?.post = posts[indexPath.item]
return cell
}
}
class PostCell: BaseCell {
var homeController: HomeController?
var userProfileController: UserProfileController?
var post: Post? {
didSet {
if let postDisplayName = post?.author {
displayName.text = postDisplayName
}
if let postImageUrl = post?.postImageUrl {
postImage.loadImageUsingCacheWithUrlString(urlString: postImageUrl)
}
if let postProfileImage = post?.avatar_image_url {
profileImage.loadImageUsingCacheWithUrlString(urlString: postProfileImage)
}
}
}
lazy var profileSegueContainer: UIView = {
let view = UIView()
view.isUserInteractionEnabled = true
return view
}()
func handleProfileSegue() {
let userProfile = UserProfileController()
let navigationUserProfile = UINavigationController(rootViewController: userProfile)
homeController?.present(navigationUserProfile, animated: true, completion: nil)
}
override func setupViews() {
super.setupViews()
let tap = UITapGestureRecognizer(target: self, action: #selector(handleProfileSegue))
profileSegueContainer.addGestureRecognizer(tap)
addSubview(profileSegueContainer)
_ = profileSegueContainer.anchor(profileImage.topAnchor, left: profileImage.leftAnchor, bottom: profileImage.bottomAnchor, right: displayName.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
}
在视图控制器的上下文中,Segue 具有非常具体的含义。您可能想改用短语 "push another view controller"。
首先,UINavigationController
通常只在一个场景中使用一次——它是跟踪一堆子视图控制器的视图控制器。您只创建其中一个,并且您可能希望将 HomeController
设置为导航控制器的 rootViewController
。
然后当用户点击视图时,您应该将其转发给您将添加到 HomeController 的方法;这将创建您的自定义 UserProfile
class,使用所需的数据配置它,然后调用:navigationController?.pushViewController(userProfile, animating: true)
有很多优秀的教程可以向您展示这一切是如何工作的。