hello I am new to programming. So I have some basic questions and then I need the solution of the problem which I am having.
I have created a Model Class
class Trip: NSObject {
var tripTitle: String
var tripSummary: String
static var trips = [Trip]()
init(tripTitle: String, tripSummary: String) {
self.tripTitle = tripTitle
self.tripSummary = tripSummary
}
class func addTrip(tripTitle: String, tripSummary: String){
let t = Trip(tripTitle: tripTitle, tripSummary: tripSummary)
trips.append(t)
}
}
TripsDetailController
#IBAction func previewButtomPressed(sender: UIButton) {
let tripTitle = tripTitleTxt.text!
let tripSummary = tripSummaryTxt.text!
Trip.addTrip(tripTitle, tripSummary: tripSummary)
// let optionaltrip = Trip(tripTitle: tripTitle, tripSummary: tripSummary)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowTripPreviewTableViewController" {
let tripPreviewTableViewController = segue.destinationViewController as! TripPreviewTableViewController
// how can I pass the object here
}
}
how can I pass the object in segue
tripPreviewTableViewController
In this class I know I have to declare a variable here also but don't know what would be the datatype and also how can I access the value
and also I want to know what would be the best approach from these two
Trip.addTrip(tripTitle, tripSummary: tripSummary)
or
let trip = Trip(tripTitle: tripTitle, tripSummary: tripSummary)
should I have to create an array and assign values or go to the second method of creating an object
Use the destinationViewController:
In the tripPreviewTableViewController you need to add new optional variable type of Trip:
var trip : Trip!
and now you can transfer your object with destinationViewController:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowTripPreviewTableViewController" {
let tripPreviewTableViewController = segue.destinationViewController as! TripPreviewTableViewController
tripPreviewTableViewController.trip = (Your Trip Object)
}
}
//Update
First you need to declare your Trip object in TripsDetailController:
var tripToPass = Trip!
then orient it with one of these ways:
tripToPass = Trip(tripTitle:"title",tripSummary:"summary")
//or get the Trip out of your trips array:
tripToPass = Trip.trips[index]
after that you can pass the trip object:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowTripPreviewTableViewController" {
let tripPreviewTableViewController = segue.destinationViewController as! TripPreviewTableViewController
tripPreviewTableViewController.trip = tripToPass
}
}
Related
In my HomeClass there is a static var globalLimit: Int = 0 and i have to pass his value in other classes, this is my prepare function
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? SelectClass {
vc.limit = Int(steppeR.value)
HomeClass.globalLimit = Int(steppeR.value)
HomeClass.globalRadiusLimit = Int(stepperRadius.value)
}
else if let np = segue.destination as? CourseClass2 {
np.categories = filteredList
np.numberPlaces = filteredList.count
np.radius = Int(stepperRadius.value)
}
}
now the problem is this, in my CourseClass2 class that i can even reach from SelectClass i have the var numberPlaces = 0 and his value is
override func viewDidLoad() {
super.viewDidLoad()
numberPlaces = HomeClass.globalLimit
}
but like you can see in my prepare function when i come in CourseClass2 directly from HomeClass i want that the value of numberPlaces = filteredList.count but of course it does not work because it goes against it numberPlaces = HomeClass.globalLimit in the viewDidload of CourseClass2, so how can i solve this problem?
Try in this way:
Set your numberPlaces var as optional:
var numberPlaces: Int?
Then check in view did load if it is nil:
override func viewDidLoad() {
super.viewDidLoad()
if numberPlaces == nil {
numberPlaces = HomeClass.globalLimit
}
}
class NewCourseViewController: UIViewController {
#IBOutlet weak var courseNameTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if segue.identifier == "newClassComplete" {
if let vcSendingToo = segue.destination as? CoursesTableViewController {
// Pass courseName to nameOfCourses Array
// Course Name
let courseName = courseNameTextField.text!
vcSendingToo.nameOfCourse = courseName
vcSendingToo.nameOfCourses.append(vcSendingToo.nameOfCourse)
}
class CoursesTableViewController: UITableViewController {
var nameOfCourses = [String]()
var nameOfCourse = ""
}
It restarts to a blank array rather than add a value to the same array. I can't find any examples that are online that'll help resolve my issue. It was working fin then stopped all of a su
Have you tried to change this line
let courseName = courseNameTextField.text!
vcSendingToo.nameOfCourse = courseName
vcSendingToo.nameOfCourses.append(vcSendingToo.nameOfCourse)
to this?
let courseName = courseNameTextField.text ?? "" //validate for nil
vcSendingToo.nameOfCourse = courseName
vcSendingToo.nameOfCourses = [courseName]
I made the variables global and removed the "vcSendingToo" properties.
I have like a social app with a sort of newsfeed. if u click on the users name from a post in the newsfeed, you will go to his profile. Now i can't retrieve the data from that specific cell/post to the other viewController.
so i have to display the user's profile, with he's username, etc. but that doesn't work?
i have a Post model:
class Post {
private var _postDescription: String!
private var _profileImageURL: String?
private var _likes: Int!
private var _username: String!
private var _postKey: String!
private var _timeStamp: String!
private var _postRef: Firebase!
var postDescription: String? {
return _postDescription
}
var likes: Int {
return _likes
}
var username: String {
return _username
}
var postKey: String {
return _postKey
}
var profileImageURL: String? {
return _profileImageURL
}
init(description: String, username: String, profileImageURL: String?) {
self._postDescription = description
self._username = username
self._profileImageURL = profileImageURL
}
init(postKey: String, dictionary: Dictionary<String, AnyObject>) {
self._postKey = postKey
if let likes = dictionary["likes"] as? Int {
self._likes = likes
}
if let desc = dictionary ["description"] as? String {
self._postDescription = desc
}
if let imgUrl = dictionary["profileImg"] as? String {
self._profileImageURL = imgUrl
}
if let user = dictionary ["username"] as? String {
self._username = user
} else {
self._username = ""
}
self._postRef = DataService.ds.REF_POST.childByAppendingPath(self._postKey)
}
}
this is my profileVC:
class ProfileVC: UIViewController {
#IBOutlet weak var username: UILabel!
var post: Post?
override func viewDidLoad() {
super.viewDidLoad()
username.text = post.username // gives me a nil error.
}
}
and i use a TapGestureRecognizer in my tableViewCell to perform the segue.
in my cellForRowAtIndexPath:
let profileLblTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(NewsVC.goToProfileScreen(_:)))
profileLblTapRecognizer.numberOfTapsRequired = 1
profileLblTapRecognizer.delegate = self
cell.usernameLabel.tag = indexPath.row
cell.usernameLabel.userInteractionEnabled = true
cell.usernameLabel.addGestureRecognizer(profileLblTapRecognizer)
and the goToProfileScreen function:
func goToProfileScreen(gesture: UITapGestureRecognizer) {
self.performSegueWithIdentifier("ProfileScreen", sender: self)
}
this is my datamodel on firebase:
UPDATE:
i tried this instead:
let profileLblTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(NewsVC.prepareForSegue(_:sender:)))
with this function:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ProfileScreen" {
if let cell = sender as? NewsCell, row = tableView.indexPathForCell(cell)?.row, vc = segue.destinationViewController as? ProfileVC {
vc.post = posts[row]
}
}
}
but that gave me an error on appDelegate: Thread 1: EXC_BAD_ACCESS(code=1, address = 0x1)
I've added this as an answer rather than a comment so that I can add and format some code examples.
When you call performSegueWithIdentifier, a NEW instance of the view controller identified by that segue is created, so all of its properties will be their defaults.
You have two ways of instantiating this view controller and setting properties before it loads. The first is the prepareForSegue option, in your case it may look something like this:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "ProfileScreen") {
let vc = segue.destinationViewController as! ProfileVC
vc.post = post
}
}
Another option is to create and present the view controller yourself, this example uses a storyboardID
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = mainStoryboard.instantiateViewControllerWithIdentifier("profileVC") as! ProfileVC
vc.post = post
presentViewController(vc, animated: false, completion: nil)
Update:
I'm not sure why you are adding a tap gesture recogniser to this, you could just use didSelectRowAtIndexPath, have a look at this other question and answer
you could have a property on your table view controller called selectedItem or something similar. and then in didSelectRowAtIndexPath set selectedItem to the item at the current index. Then in prepare for segue you would just do vc.post = selectedItem
Update Two:
After the op sharing their code privately, I noticed that the issue is that the user is using tapGestureRecogniser in the tableView. I added some code into the called function to get the row in which contained the tapped view, once I had the indexPath it was then easy to store it in a temporary property and retreive later in the prepareForSegue method, details below
// temp property
var selectedPost:Post?
// function called on tap
func viewProfile(sender:UITapGestureRecognizer) {
if (sender.state == UIGestureRecognizerState.Ended) {
let point = sender.locationInView(self.tableView)
if let indexPath = self.tableView.indexPathForRowAtPoint(point) {
selectedPost = self.posts[indexPath.row]
performSegueWithIdentifier("ProfileScreen", sender: self)
}
}
}
// Prepare for segue
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "ProfileScreen") {
let vc = segue.destinationViewController as! ProfileVC
if let post = selectedPost {
vc.post = post
}
}
}
I don't understand what is ambiguous about my use of book.numberOfPages in my TableViewController. I'm not having any problems with using any of the other attributes. There shouldn't be any ambiguity here: I have defined it as a Float in the data model editor and at the top of the TableViewController.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showBookDetail" {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
let book: AnyObject = addBookViewController.fetchedResultsController.objectAtIndexPath(indexPath) as! Book
var detailViewController:BookDetailViewController = segue.destinationViewController as! BookDetailViewController
detailViewController.title = book.name
detailViewController.pagesReadText = "\(Int(book.pagesRead))"
detailViewController.timeReadText = "\(Int(book.timeRead))"
println(book.numberOfPages)
}
}
Probably you can't declare book as AnyObject so the compiler knows that it is a Book...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showBookDetail" {
let indexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
let book = addBookViewController.fetchedResultsController.objectAtIndexPath(indexPath) as! Book
var detailViewController:BookDetailViewController = segue.destinationViewController as! BookDetailViewController
detailViewController.title = book.name
detailViewController.pagesReadText = "\(Int(book.pagesRead))"
detailViewController.timeReadText = "\(Int(book.timeRead))"
println(book.numberOfPages)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "shoesDetails" {
let indexPath = self.table.indexPathForSelectedRow()
let shoesCon:ShoesTableControler = segue.destinationViewController as! ShoesTableControler
let shoesCategories:RepoSitory = arrofRepository[indexPath!.row]
shoesCon.object = shoesCategories
}
}
class ShoesTableControler: UIViewController {
var object = [ProductShoes]()
}
class ProductShoes {
var product_id : String
var product_name : String
init(json :NSDictionary) {
self.product_id = json["product_id"] as! String
self.product_name = json["product_name"] as! String
}
class RepoSitory {
var name : String
var ids : String
init(json :NSDictionary) {
self.name = json["category_name"] as! String
self.ids = json["id"] as! String
}
}
I have 3 classes in firstViewController. We show the data it's done. After that, when user click on specific cell, then show the data. Now I have created the ShoesTableController and in ShoesTableController we create the Product Class obj. I want to access this. The problem is in this line in Objective C. I am doing this and it is working perfect but in swift it does know what happened:
shoesCon.object = shoesCategories
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "shoesDetails" {
let indexPath = self.table.indexPathForSelectedRow()
let shoesCon:ShoesTableControler = segue.destinationViewController as! ShoesTableControler
let shoesCategories:RepoSitory = arrofRepository[indexPath!.row]
shoesCon.object = shoesCategories
}
}
class ShoesTableControler: UIViewController {
var object : RepoSitory?
its solve my problem i have my own mistake sorry for posting this question