Perform Segue from a custom Button
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I created a custom button to include in the button the information I need:
class CustomButton: UIButton {
var urlString: String?
var documentType: String?
var requestEntity: String?
var requestSortBy: [NSSortDescriptor]?
var requestPredicate: NSPredicate?
}
When I create the cells in the collectionView (embedded in a tableView) I include the information in my custom button, called documentTypeButton
. And also the target for executing the function HomeTableViewController.documentTypeButtonTapped(_:)
to perform the segue.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().value(forKey: "language") as! String
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.documentTypeButton.documentType = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].name
cell.documentTypeButton.requestEntity = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].entityName
cell.documentTypeButton.requestSortBy = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].sortBy
cell.documentTypeButton.requestPredicate = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].predicate
cell.documentTypeButton.addTarget(nil, action: #selector(HomeTableViewController.documentTypeButtonTapped(_:)), for: .touchUpInside)
return cell
}
And the, in the HomeTableViewController
I have the function to execute when touching inside the button:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
print(sender.documentType)
print(sender.requestEntity)
}
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
destination.titlePassed = sender.documentType!.localized(lang: languageSelected)
destination.requestedEntity = sender.requestEntity
destination.requestedSortBy = sender.requestSortBy
destination.requestedPredicate = sender.requestPredicate
}
}
The print statements above work well and print the information. And the segue goes to the DocumentListTableViewController
.
In the viewDidLoad
of the DocumentListTableViewController
I added the following:
override func viewDidLoad() {
super.viewDidLoad()
print(titlePassed)
print(requestedEntity)
}
And the two print statements print nil
.
I guess the problem should be in the prepareForSegue
, maybe with the sender... I don't know.
Any help would be appreciated.
ios swift xcode
add a comment |
I created a custom button to include in the button the information I need:
class CustomButton: UIButton {
var urlString: String?
var documentType: String?
var requestEntity: String?
var requestSortBy: [NSSortDescriptor]?
var requestPredicate: NSPredicate?
}
When I create the cells in the collectionView (embedded in a tableView) I include the information in my custom button, called documentTypeButton
. And also the target for executing the function HomeTableViewController.documentTypeButtonTapped(_:)
to perform the segue.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().value(forKey: "language") as! String
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.documentTypeButton.documentType = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].name
cell.documentTypeButton.requestEntity = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].entityName
cell.documentTypeButton.requestSortBy = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].sortBy
cell.documentTypeButton.requestPredicate = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].predicate
cell.documentTypeButton.addTarget(nil, action: #selector(HomeTableViewController.documentTypeButtonTapped(_:)), for: .touchUpInside)
return cell
}
And the, in the HomeTableViewController
I have the function to execute when touching inside the button:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
print(sender.documentType)
print(sender.requestEntity)
}
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
destination.titlePassed = sender.documentType!.localized(lang: languageSelected)
destination.requestedEntity = sender.requestEntity
destination.requestedSortBy = sender.requestSortBy
destination.requestedPredicate = sender.requestPredicate
}
}
The print statements above work well and print the information. And the segue goes to the DocumentListTableViewController
.
In the viewDidLoad
of the DocumentListTableViewController
I added the following:
override func viewDidLoad() {
super.viewDidLoad()
print(titlePassed)
print(requestedEntity)
}
And the two print statements print nil
.
I guess the problem should be in the prepareForSegue
, maybe with the sender... I don't know.
Any help would be appreciated.
ios swift xcode
add a comment |
I created a custom button to include in the button the information I need:
class CustomButton: UIButton {
var urlString: String?
var documentType: String?
var requestEntity: String?
var requestSortBy: [NSSortDescriptor]?
var requestPredicate: NSPredicate?
}
When I create the cells in the collectionView (embedded in a tableView) I include the information in my custom button, called documentTypeButton
. And also the target for executing the function HomeTableViewController.documentTypeButtonTapped(_:)
to perform the segue.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().value(forKey: "language") as! String
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.documentTypeButton.documentType = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].name
cell.documentTypeButton.requestEntity = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].entityName
cell.documentTypeButton.requestSortBy = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].sortBy
cell.documentTypeButton.requestPredicate = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].predicate
cell.documentTypeButton.addTarget(nil, action: #selector(HomeTableViewController.documentTypeButtonTapped(_:)), for: .touchUpInside)
return cell
}
And the, in the HomeTableViewController
I have the function to execute when touching inside the button:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
print(sender.documentType)
print(sender.requestEntity)
}
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
destination.titlePassed = sender.documentType!.localized(lang: languageSelected)
destination.requestedEntity = sender.requestEntity
destination.requestedSortBy = sender.requestSortBy
destination.requestedPredicate = sender.requestPredicate
}
}
The print statements above work well and print the information. And the segue goes to the DocumentListTableViewController
.
In the viewDidLoad
of the DocumentListTableViewController
I added the following:
override func viewDidLoad() {
super.viewDidLoad()
print(titlePassed)
print(requestedEntity)
}
And the two print statements print nil
.
I guess the problem should be in the prepareForSegue
, maybe with the sender... I don't know.
Any help would be appreciated.
ios swift xcode
I created a custom button to include in the button the information I need:
class CustomButton: UIButton {
var urlString: String?
var documentType: String?
var requestEntity: String?
var requestSortBy: [NSSortDescriptor]?
var requestPredicate: NSPredicate?
}
When I create the cells in the collectionView (embedded in a tableView) I include the information in my custom button, called documentTypeButton
. And also the target for executing the function HomeTableViewController.documentTypeButtonTapped(_:)
to perform the segue.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().value(forKey: "language") as! String
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.documentTypeButton.documentType = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].name
cell.documentTypeButton.requestEntity = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].entityName
cell.documentTypeButton.requestSortBy = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].sortBy
cell.documentTypeButton.requestPredicate = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row].predicate
cell.documentTypeButton.addTarget(nil, action: #selector(HomeTableViewController.documentTypeButtonTapped(_:)), for: .touchUpInside)
return cell
}
And the, in the HomeTableViewController
I have the function to execute when touching inside the button:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
print(sender.documentType)
print(sender.requestEntity)
}
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
destination.titlePassed = sender.documentType!.localized(lang: languageSelected)
destination.requestedEntity = sender.requestEntity
destination.requestedSortBy = sender.requestSortBy
destination.requestedPredicate = sender.requestPredicate
}
}
The print statements above work well and print the information. And the segue goes to the DocumentListTableViewController
.
In the viewDidLoad
of the DocumentListTableViewController
I added the following:
override func viewDidLoad() {
super.viewDidLoad()
print(titlePassed)
print(requestedEntity)
}
And the two print statements print nil
.
I guess the problem should be in the prepareForSegue
, maybe with the sender... I don't know.
Any help would be appreciated.
ios swift xcode
ios swift xcode
edited Nov 25 '18 at 7:58
Arie Pinto
9041816
9041816
asked Nov 24 '18 at 21:13
jRuMoLjRuMoL
335
335
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
Try to pass sender
parameter in performSegue()
method like this:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: sender)
print(sender.documentType)
print(sender.requestEntity)
}
Problem is that you are instantiating new object of type CustomButton() instead passing sender
.
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
add a comment |
The issue is that you pass a new (empty) instance of CustomButton
in the performSegue
call rather than the sender
of the action.
But your design to create a custom button as data container is still worse. Don't do that. It's horrible.
There is a much easier and more efficient solution:
In AllDocumentsCollectionViewCell
create a callback closure
var callback : (()->Void)?
and an IBAction
and connect it to the button, the callback is called when the button is tapped.
@IBAction func documentTypeButtonTapped(_ sender: UIButton) {
callback?()
}
In HomeTableViewController
assign a closure to the callback, perform the segue in there and pass the item of the data source array.
But the way calling UserDefaults().value(
in each call of collectionView
and getting the same item for index path 4 times is very very inefficient. And never use value(forKey
. There is string(forKey
in UserDefaults
.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().string(forKey: "language")!
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.callback { [weak self] in
let item = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row]
self?.performSegue(withIdentifier: "goToDocumentList", sender: item)
}
return cell
}
In prepare(for
get the data source item (I have no idea what type it is) and retrieve the information from there. You can even pass the entire item to the destination view controller.
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().string(forKey: "language")!
if let destination = segue.destination as? DocumentListTableViewController {
let item = sender as! WhatEverTheTypeIs // change this to the real type
destination.titlePassed = item.name.localized(lang: languageSelected)
destination.requestedEntity = item.entityName
destination.requestedSortBy = item.sortBy
destination.requestedPredicate = item.predicate
}
}
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
add a comment |
In your performSegue call your are sending a new instance of CustomButton
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
So its parameters are going to be nil in the next view controller, you need to send the sender instead.
performSegue(withIdentifier: "goToDocumentList", sender: sender)
You need to override prepareForSegue
for it to be called, no need to change to its signature, you could write it like this instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
let myCustomButton = sender as! CustomButton
destination.titlePassed = myCustomButton.documentType!.localized(lang: languageSelected)
destination.requestedEntity = myCustomButton.requestEntity
destination.requestedSortBy = myCustomButton.requestSortBy
destination.requestedPredicate = myCustomButton.requestPredicate
}
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462424%2fperform-segue-from-a-custom-button%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
Try to pass sender
parameter in performSegue()
method like this:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: sender)
print(sender.documentType)
print(sender.requestEntity)
}
Problem is that you are instantiating new object of type CustomButton() instead passing sender
.
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
add a comment |
Try to pass sender
parameter in performSegue()
method like this:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: sender)
print(sender.documentType)
print(sender.requestEntity)
}
Problem is that you are instantiating new object of type CustomButton() instead passing sender
.
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
add a comment |
Try to pass sender
parameter in performSegue()
method like this:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: sender)
print(sender.documentType)
print(sender.requestEntity)
}
Problem is that you are instantiating new object of type CustomButton() instead passing sender
.
Try to pass sender
parameter in performSegue()
method like this:
@objc func documentTypeButtonTapped(_ sender: CustomButton) {
performSegue(withIdentifier: "goToDocumentList", sender: sender)
print(sender.documentType)
print(sender.requestEntity)
}
Problem is that you are instantiating new object of type CustomButton() instead passing sender
.
answered Nov 24 '18 at 21:17
bezoadambezoadam
1041210
1041210
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
add a comment |
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Still returns nil for the two print statements in the DocumentListTableViewController
– jRuMoL
Nov 24 '18 at 21:20
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
Try to use breakpoint if assign statements in prepare method are invoked and have proper data.
– bezoadam
Nov 24 '18 at 21:24
add a comment |
The issue is that you pass a new (empty) instance of CustomButton
in the performSegue
call rather than the sender
of the action.
But your design to create a custom button as data container is still worse. Don't do that. It's horrible.
There is a much easier and more efficient solution:
In AllDocumentsCollectionViewCell
create a callback closure
var callback : (()->Void)?
and an IBAction
and connect it to the button, the callback is called when the button is tapped.
@IBAction func documentTypeButtonTapped(_ sender: UIButton) {
callback?()
}
In HomeTableViewController
assign a closure to the callback, perform the segue in there and pass the item of the data source array.
But the way calling UserDefaults().value(
in each call of collectionView
and getting the same item for index path 4 times is very very inefficient. And never use value(forKey
. There is string(forKey
in UserDefaults
.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().string(forKey: "language")!
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.callback { [weak self] in
let item = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row]
self?.performSegue(withIdentifier: "goToDocumentList", sender: item)
}
return cell
}
In prepare(for
get the data source item (I have no idea what type it is) and retrieve the information from there. You can even pass the entire item to the destination view controller.
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().string(forKey: "language")!
if let destination = segue.destination as? DocumentListTableViewController {
let item = sender as! WhatEverTheTypeIs // change this to the real type
destination.titlePassed = item.name.localized(lang: languageSelected)
destination.requestedEntity = item.entityName
destination.requestedSortBy = item.sortBy
destination.requestedPredicate = item.predicate
}
}
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
add a comment |
The issue is that you pass a new (empty) instance of CustomButton
in the performSegue
call rather than the sender
of the action.
But your design to create a custom button as data container is still worse. Don't do that. It's horrible.
There is a much easier and more efficient solution:
In AllDocumentsCollectionViewCell
create a callback closure
var callback : (()->Void)?
and an IBAction
and connect it to the button, the callback is called when the button is tapped.
@IBAction func documentTypeButtonTapped(_ sender: UIButton) {
callback?()
}
In HomeTableViewController
assign a closure to the callback, perform the segue in there and pass the item of the data source array.
But the way calling UserDefaults().value(
in each call of collectionView
and getting the same item for index path 4 times is very very inefficient. And never use value(forKey
. There is string(forKey
in UserDefaults
.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().string(forKey: "language")!
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.callback { [weak self] in
let item = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row]
self?.performSegue(withIdentifier: "goToDocumentList", sender: item)
}
return cell
}
In prepare(for
get the data source item (I have no idea what type it is) and retrieve the information from there. You can even pass the entire item to the destination view controller.
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().string(forKey: "language")!
if let destination = segue.destination as? DocumentListTableViewController {
let item = sender as! WhatEverTheTypeIs // change this to the real type
destination.titlePassed = item.name.localized(lang: languageSelected)
destination.requestedEntity = item.entityName
destination.requestedSortBy = item.sortBy
destination.requestedPredicate = item.predicate
}
}
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
add a comment |
The issue is that you pass a new (empty) instance of CustomButton
in the performSegue
call rather than the sender
of the action.
But your design to create a custom button as data container is still worse. Don't do that. It's horrible.
There is a much easier and more efficient solution:
In AllDocumentsCollectionViewCell
create a callback closure
var callback : (()->Void)?
and an IBAction
and connect it to the button, the callback is called when the button is tapped.
@IBAction func documentTypeButtonTapped(_ sender: UIButton) {
callback?()
}
In HomeTableViewController
assign a closure to the callback, perform the segue in there and pass the item of the data source array.
But the way calling UserDefaults().value(
in each call of collectionView
and getting the same item for index path 4 times is very very inefficient. And never use value(forKey
. There is string(forKey
in UserDefaults
.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().string(forKey: "language")!
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.callback { [weak self] in
let item = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row]
self?.performSegue(withIdentifier: "goToDocumentList", sender: item)
}
return cell
}
In prepare(for
get the data source item (I have no idea what type it is) and retrieve the information from there. You can even pass the entire item to the destination view controller.
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().string(forKey: "language")!
if let destination = segue.destination as? DocumentListTableViewController {
let item = sender as! WhatEverTheTypeIs // change this to the real type
destination.titlePassed = item.name.localized(lang: languageSelected)
destination.requestedEntity = item.entityName
destination.requestedSortBy = item.sortBy
destination.requestedPredicate = item.predicate
}
}
The issue is that you pass a new (empty) instance of CustomButton
in the performSegue
call rather than the sender
of the action.
But your design to create a custom button as data container is still worse. Don't do that. It's horrible.
There is a much easier and more efficient solution:
In AllDocumentsCollectionViewCell
create a callback closure
var callback : (()->Void)?
and an IBAction
and connect it to the button, the callback is called when the button is tapped.
@IBAction func documentTypeButtonTapped(_ sender: UIButton) {
callback?()
}
In HomeTableViewController
assign a closure to the callback, perform the segue in there and pass the item of the data source array.
But the way calling UserDefaults().value(
in each call of collectionView
and getting the same item for index path 4 times is very very inefficient. And never use value(forKey
. There is string(forKey
in UserDefaults
.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let languageSelected = UserDefaults().string(forKey: "language")!
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "allDocumentsItemCell", for: indexPath) as! AllDocumentsCollectionViewCell
cell.callback { [weak self] in
let item = Catalog.sharedInstance.allSections[allDocumentsSection!].singleItems[indexPath.row]
self?.performSegue(withIdentifier: "goToDocumentList", sender: item)
}
return cell
}
In prepare(for
get the data source item (I have no idea what type it is) and retrieve the information from there. You can even pass the entire item to the destination view controller.
func prepare(for segue: UIStoryboardSegue, sender: CustomButton) {
let languageSelected = UserDefaults().string(forKey: "language")!
if let destination = segue.destination as? DocumentListTableViewController {
let item = sender as! WhatEverTheTypeIs // change this to the real type
destination.titlePassed = item.name.localized(lang: languageSelected)
destination.requestedEntity = item.entityName
destination.requestedSortBy = item.sortBy
destination.requestedPredicate = item.predicate
}
}
edited Nov 24 '18 at 21:46
answered Nov 24 '18 at 21:33
vadianvadian
157k17168193
157k17168193
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
add a comment |
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Thank you very much for your answer. When you say "In HomeTableViewController assign a closure to the callback, perform the segue in there and pass the item of the data source array." I have no idea about how to do that. I have been searching but it is difficult for me to understand it.
– jRuMoL
Nov 25 '18 at 14:55
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
Actually my answer contains all the code you need.
– vadian
Nov 25 '18 at 17:46
add a comment |
In your performSegue call your are sending a new instance of CustomButton
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
So its parameters are going to be nil in the next view controller, you need to send the sender instead.
performSegue(withIdentifier: "goToDocumentList", sender: sender)
You need to override prepareForSegue
for it to be called, no need to change to its signature, you could write it like this instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
let myCustomButton = sender as! CustomButton
destination.titlePassed = myCustomButton.documentType!.localized(lang: languageSelected)
destination.requestedEntity = myCustomButton.requestEntity
destination.requestedSortBy = myCustomButton.requestSortBy
destination.requestedPredicate = myCustomButton.requestPredicate
}
}
add a comment |
In your performSegue call your are sending a new instance of CustomButton
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
So its parameters are going to be nil in the next view controller, you need to send the sender instead.
performSegue(withIdentifier: "goToDocumentList", sender: sender)
You need to override prepareForSegue
for it to be called, no need to change to its signature, you could write it like this instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
let myCustomButton = sender as! CustomButton
destination.titlePassed = myCustomButton.documentType!.localized(lang: languageSelected)
destination.requestedEntity = myCustomButton.requestEntity
destination.requestedSortBy = myCustomButton.requestSortBy
destination.requestedPredicate = myCustomButton.requestPredicate
}
}
add a comment |
In your performSegue call your are sending a new instance of CustomButton
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
So its parameters are going to be nil in the next view controller, you need to send the sender instead.
performSegue(withIdentifier: "goToDocumentList", sender: sender)
You need to override prepareForSegue
for it to be called, no need to change to its signature, you could write it like this instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
let myCustomButton = sender as! CustomButton
destination.titlePassed = myCustomButton.documentType!.localized(lang: languageSelected)
destination.requestedEntity = myCustomButton.requestEntity
destination.requestedSortBy = myCustomButton.requestSortBy
destination.requestedPredicate = myCustomButton.requestPredicate
}
}
In your performSegue call your are sending a new instance of CustomButton
performSegue(withIdentifier: "goToDocumentList", sender: CustomButton())
So its parameters are going to be nil in the next view controller, you need to send the sender instead.
performSegue(withIdentifier: "goToDocumentList", sender: sender)
You need to override prepareForSegue
for it to be called, no need to change to its signature, you could write it like this instead:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let languageSelected = UserDefaults().value(forKey: "language") as! String
if let destination = segue.destination as? DocumentListTableViewController {
let myCustomButton = sender as! CustomButton
destination.titlePassed = myCustomButton.documentType!.localized(lang: languageSelected)
destination.requestedEntity = myCustomButton.requestEntity
destination.requestedSortBy = myCustomButton.requestSortBy
destination.requestedPredicate = myCustomButton.requestPredicate
}
}
edited Nov 24 '18 at 21:48
answered Nov 24 '18 at 21:36
Arie PintoArie Pinto
9041816
9041816
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53462424%2fperform-segue-from-a-custom-button%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown