How to refresh a view?

Hi,


I’ve been trying to refresh a view to reload its data,

for example, let’s say the user has a name called Bill,

if im going to another view to change his name to Jack,

when Im going back to the previous view to see his name changed,

it’s still Bill, only if I’m running the app again it’s showing the changed result- Jack.


Is there a way to refresh the view every time I’m going back to that view?

Replies

The standard approach is to repopulate all your view objects (labels, text fields etc.) in your view controller’s viewWillAppear. Or depending on how your app is structured, you might need some sort of notification (NSNotificationCenter works well) that the view controller would respond to when the model data changes.


Typically when there are problems in this area, it’s because you have not separated the view from the model, in your mind at least. It may be useful to read up on the MVC (model-view-controller) design pattern. Without seeing any of your code it’s hard to suggest anything specific though.

You can also use delegation, to update the initial view when you go back.


Typical set up as follows:

You have VC1 and VC2 ; you want to update a field in VC1 when you change a text in VC2.


Declare a protocol

protocol UpdateVC1 {
    func updateName(newName: String)
}


Declare that VC1 conforms to it, and implement it:

Set the delegate property of VC2 when you segue

class VC1: UIViewController, UpdateVC1 {
    @IBOutlet weak var userNameField: UITextField!

    func updateName(newName: String) {
        userNameField.text = newName
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? VC2 {
            destination.delegate = self
        }
    }

}



In VC2 declare a delegate property:

class VC2: UIViewController {

    var delegate: UpdateVC1?

Then, when you change the field with name, invoke the delegate


        delegate?.updateName(newName: name)



Another way is to reload data in viewWillAppear (not only in viewDidload because it is not called when you return)

That’s a good idea!

Is it work for button.isHidden too?


I don’t know how to use ViewWillAppear, I tried print() and it works to print every time I open the view,

but for other things like if my data has changed, or changing text it stays the way I opened the view for the first time.


For example if I put in viewWillAppear this code:

for person in peopleWhoLike{

If person = currentUser {

likeButton.isHidden = true

unlikeButton.isHidden = false

}

}

So if the current user liked it,

for the first time I open the view the likeButton is hidden and unlikeButton isn’t.

But if im going back and the user unliked it, the second time I open the view it stays the same.

Yes, delegate can work as well to hide a button.


You use the same pattern as for

func updateName(newName: String)


by declaring

func updateButtons(likeIt: Bool)


class VC1: UIViewController, UpdateVC1 {
    @IBOutlet weak var userNameField: UITextField!
    @IBOutlet weak var likeButton: UIButton!
    @IBOutlet weak var unlikeButton: UIButton!

    func updateName(newName: String) {
        userNameField.text = newName
    }

  func updateButtosn(likeIt: Bool) {
     likeButton.isHidden = !likeIt     // hidden if not likeIt
     unlikeButton.isHidden = likeIt
  }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? VC2 {
            destination.delegate = self
        }
    }

}


You will call where needed in VC2 by

        delegate?.updateButtosn(likeIt: person == currentUser)


In viewWillAppear


you wrote:

If person = currentUser

I suppose you mean


If person == currentUser

the code doesnt work.


Ive managed to open the second view(PostCommentController) as a present,

and if i'm doing like\unlike and when I go back,

it reloads the first view (NewsViewController) and been updated.

but if i'm on NewsViewController and I'm like\unlike, it doesnt update the PostCommentController immediately,

only when I'm presenting it for the second time.


Ive tried this:


protocol UpdateVC1 {
    func updateButtons(likeIt: Bool)
}


class PostCommentController: UIViewController, UITableViewDelegate, UITableViewDataSource, UpdateVC1 {
   
    func updateButtons(likeIt: Bool) {
        likeBtn.isHidden = !likeIt
        unlikeBtn.isHidden = likeIt
    }
   
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? NewsViewController {
            destination.delegate = self
        }
    }

 @IBOutlet weak var likeBtn: UIButton!
 @IBOutlet weak var unlikeBtn: UIButton!


class NewsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, 
commentButtonDelegate {

var delegate: UpdateVC1?

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
 -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "postCell", for: indexPath)
 as! PostCell
       
        let inverseIndex = self.posts.count - indexPath.row - 1
       
        cell.postImage.downloadImage(from: self.posts[inverseIndex].pathToImage)
        cell.authorLabel.text = self.posts[inverseIndex].author
        cell.likeLabel.text = "\(self.posts[inverseIndex].likes!) Likes"
        cell.postID = self.posts[inverseIndex].postID
        cell.authorImage.downloadImage(from: self.posts[inverseIndex].authorImage)
       
        let string = self.posts[inverseIndex].timeAgo
        let df = DateFormatter()
        df.dateFormat = "yyyy/MM/dd, H:mm:ss"
        let result = df.date(from: string!)
       
        let timeDate = timeAgoSinceDate(result!)
            cell.timeLabel.text = timeDate
       
        cell.commentBtn.addTarget(self, action: #selector(buttonClicked(sender:)), for: .touchUpInside)
      
       
        for person in self.posts[inverseIndex].peopleWhoLike{
            if person == Auth.auth().currentUser!.uid{
                cell.unlikeBtn.isHidden = false
                cell.likeBtn.isHidden = true
               delegate?.updateButtons(likeIt: person == Auth.auth().currentUser?.uid)
                break
            }
       
        }
       
      cell.indexPath = indexPath
        cell.delegate = self
       
        return cell
    }

How do you transition from VC1 to VC2 ?


With a segue ?


And how do you return to VC1? Do you have a nvigation controller ? Do you return with unwindSegue ?

vc1 to vc2:


func commentButtonTapped(at index: IndexPath) {
    
        let vc = storyboard?.instantiateViewController(withIdentifier: "PostCommentController") 
as? PostCommentController
        let inverseIndex = self.posts.count - index.row - 1
       
        let string = self.posts[inverseIndex].timeAgo
        let df = DateFormatter()
        df.dateFormat = "yyyy/MM/dd, H:mm:ss"
        let result = df.date(from: string!)
       
        let timeDate = timeAgoSinceDate(result!)
       
        vc?.postID = self.posts[inverseIndex].postID
        print(self.posts[inverseIndex].postID)
        vc?.authorName = self.posts[inverseIndex].author
        vc?.authorPic = self.posts[inverseIndex].authorImage
        vc?.postPic = self.posts[inverseIndex].pathToImage
        vc?.likesText = "\(self.posts[inverseIndex].likes!) Likes"
        vc?.time = timeDate
       
        vc?.likesCount = self.posts[inverseIndex].peopleWhoLike
    
        self.present(vc!, animated: true, completion: nil)
  
    }


vc2 to vc1:


@IBActionfunc backButton(_ sender: Any) {
        let tabVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:
 "NavigationTab") as! UITabBarController
        tabVC.selectedIndex = 0
       
        self.present(tabVC, animated: true, completion: nil)
       
    }

You should not use present() in backButton.


If you do so, you create a new instance of VC1 ! Hence, the button you have set with the delegate is the one of the old instance (that's what you did in prepare for segue), not the one of the new that you have stacked over !


Small drawing can illustrate

______________________

| VC1- 1st instance | ___________________

| VC2.delegate = me | ----- segue ----> | VC2 |

|_______button of 1st ___| creates instance| delegate = VC1.1st|

Î |___________________|

i_________ unwind or dismiss -----i |

|

______________________ |

| VC1- 2nd instance | < --- present -----------|

| | creates a new instance of VC1

|_______button of 2nd __–|

So, you should return with unwind segue (or a dismiss of VC2):


In VC1, create:


    @IBAction func unwindToViewController1(_ sender: UIStoryboardSegue) {
        print("I just unwind")
    }

In IB, control-drag from the back button to the exit at top right of VC2 window, and select unwindToViewController1


Remove the connection from backButton to backButton IBAction, and comment out the IBAction.


That should work now.


Anoter way is to dismiss VC2 in backButton.


self.dismiss(animated: true, completion: nil)

we're back at the start.


It doesn't reload the view when I dismiss\unwind so it doesnt update

if the user liked\unliked the post.

OK, so show the complete code of VC1 and VC2, to see what's happening.

SOmething not clear.

In VC1, there is only one like / unlike button, or a button in each cell ?



delegate?.updateButtons(likeIt: person == Auth.auth().currentUser?.uid)

should not be in collectionView(cellForItemAt) but in the button action.

vc1:


protocol UpdateVC1 {
    func updateButtons(likeIt: Bool)
}

import UIKit
import Firebase

class NewsViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, 
commentButtonDelegate {
   
    @IBOutlet weak var collectionView: UICollectionView!

    var posts = [Post]()
    var AFan = [String]()

        override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
         
         fetchPosts()
            self.view.setNeedsLayout()
            self.loadView() 
    }
 
    var delegate: UpdateVC1?
   
   
    func fetchPosts(){
        let ref = Database.database().reference()
        ref.child("users").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
            let users = snapshot.value as! [String : AnyObject]
            for (_,value) in users {
                if let uid = value["uid"] as? String{
                    let userImage = value["urlToImage"] as? String
                    if uid == Auth.auth().currentUser?.uid{
                        if let AFanOf = value["a fan"] as? [String : String]{
                            for(_,user) in AFanOf{
                                self.AFan.append(user)
                            }
                        }
                        self.AFan.append(Auth.auth().currentUser!.uid)
                        ref.child("posts").queryOrderedByKey().observeSingleEvent(of: .value, with: {(snap) in
                          
                            for postSnapshot in snap.children.allObjects as! [DataSnapshot] {
                                let value = postSnapshot.value as! [String : AnyObject]
                                if let userID = value["userID"] as? String{
                                   
                                    for each in self.AFan{
                                        if each == userID{
                                            let posst = Post()
                                            if let author = value["author"] as? String, 
let likes = value["likes"] as? Int, 
let pathToImage = value["pathToImage"] as? String, 
let postID = value["postID"] as? String{
                                                posst.author = author
                                                posst.likes = likes
                                                posst.pathToImage = pathToImage
                                                posst.postID = postID
                                                posst.authorImage = userImage
                                                if let people = value["peopleWhoLike"] as? [String : AnyObject]{
                                                    for (_,person) in people{
                                                        posst.peopleWhoLike.append(person as! String)
                                                    }
                                                }
                                               
                                               
                                                if let pastDate = value["createdAt"] as? String{
                                                  
                                                 
                                                    posst.timeAgo = pastDate
                                                   
                                                }

                                                self.posts.append(posst)
                                            }
                                        }
                                    }
                                  
                                    self.collectionView.reloadData()
                                }
                            }
                           
                        })
                    }
                }
            }
           
        })
        
        ref.removeAllObservers()
    }
   

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
   
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.posts.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) 
-> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "postCell", for: indexPath) 
as! PostCell
       
        let inverseIndex = self.posts.count - indexPath.row - 1
       
        cell.postImage.downloadImage(from: self.posts[inverseIndex].pathToImage)
        cell.authorLabel.text = self.posts[inverseIndex].author
        cell.likeLabel.text = "\(self.posts[inverseIndex].likes!) Likes"
        cell.postID = self.posts[inverseIndex].postID
        cell.authorImage.downloadImage(from: self.posts[inverseIndex].authorImage)
       
        let string = self.posts[inverseIndex].timeAgo
        let df = DateFormatter()
        df.dateFormat = "yyyy/MM/dd, H:mm:ss"
        let result = df.date(from: string!)
       
        let timeDate = timeAgoSinceDate(result!)
            cell.timeLabel.text = timeDate
       
        cell.commentBtn.addTarget(self, action: #selector(buttonClicked(sender:)), for: .touchUpInside)
      
       
        for person in self.posts[inverseIndex].peopleWhoLike{
            if person == Auth.auth().currentUser!.uid{
                cell.unlikeBtn.isHidden = false
                cell.likeBtn.isHidden = true
               delegate?.updateButtons(likeIt: person == Auth.auth().currentUser?.uid)
                break
            }
       
        }
       
        if cell.likeBtn.isHidden == true{
            delegate?.updateButtons(likeIt: false)
        }else{
            delegate?.updateButtons(likeIt: true)
        }
       
      cell.indexPath = indexPath
        cell.delegate = self
       
        return cell
    }
   
    @objc func buttonClicked(sender:UIButton)
    {
    }
   
    func commentButtonTapped(at index: IndexPath) {
    
        let vc = storyboard?.instantiateViewController(withIdentifier: "PostCommentController") 
as? PostCommentController
        let inverseIndex = self.posts.count - index.row - 1
       
        let string = self.posts[inverseIndex].timeAgo
        let df = DateFormatter()
        df.dateFormat = "yyyy/MM/dd, H:mm:ss"
        let result = df.date(from: string!)
       
        let timeDate = timeAgoSinceDate(result!)
       
        vc?.postID = self.posts[inverseIndex].postID
        print(self.posts[inverseIndex].postID)
        vc?.authorName = self.posts[inverseIndex].author
        vc?.authorPic = self.posts[inverseIndex].authorImage
        vc?.postPic = self.posts[inverseIndex].pathToImage
        vc?.likesText = "\(self.posts[inverseIndex].likes!) Likes"
        vc?.time = timeDate
       
        vc?.likesCount = self.posts[inverseIndex].peopleWhoLike
       
       
       
        self.present(vc!, animated: true, completion: nil)
       
       
       
    }
   
    @IBAction func unwindToViewController1(_ sender: UIStoryboardSegue) {
        print("I just unwind")
    } 
}


vc2:


import UIKit
import Firebase

class PostCommentController: UIViewController, UITableViewDelegate, UITableViewDataSource, UpdateVC1 {
   
    func updateButtons(likeIt: Bool) {
        likeBtn.isHidden = !likeIt
        unlikeBtn.isHidden = likeIt
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? NewsViewController {
            destination.delegate = self
        }
    }
   
    @IBOutlet weak var tableview: UITableView!
   
   
    @IBOutlet weak var postImage: UIImageView!
    @IBOutlet weak var authorLabel: UILabel!
    @IBOutlet weak var likeLabel: UILabel!
    @IBOutlet weak var likeBtn: UIButton!
    @IBOutlet weak var unlikeBtn: UIButton!
    @IBOutlet weak var authorImage: UIImageView!
    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var backButton: UIBarButtonItem!
   
    var postID: String!
    var authorName = ""
    var authorPic = ""
    var postPic = ""
    var likesText = ""
    var time = ""
    var likesCount: [String] = []
   
    @IBAction func likePressed(_ sender: Any) {
        self.likeBtn.isEnabled = false
        let ref = Database.database().reference()
        let keyToPost = ref.child("posts").childByAutoId().key
       
        ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snapshot) in
            if let post = snapshot.value as? [String : AnyObject]{
               
                let  updateLikes: [String : Any] = ["peopleWhoLike/\(keyToPost!)" : 
Auth.auth().currentUser!.uid]
                ref.child("posts").child(self.postID).updateChildValues(updateLikes, withCompletionBlock: { 
(error, reff) in
                    if error == nil{
                        ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snap) in
                            if let properties = snap.value as? [String : AnyObject]{
                                if let likes = properties["peopleWhoLike"] as? [String : AnyObject]{
                                    let count = likes.count
                                    self.likeLabel.text = "\(count) Likes"
                                    let update = ["likes" : count]
                                    ref.child("posts").child(self.postID).updateChildValues(update)
                                   
                                  
                                    self.likeBtn.isHidden = true
                                    self.unlikeBtn.isHidden = false
                                    self.likeBtn.isEnabled = true
                                }
                            }
                        })
                    }else{
                       
                    }
                })
            }
        })
        ref.removeAllObservers()
    }
   
    @IBAction func unlikePressed(_ sender: Any) {
        self.unlikeBtn.isEnabled = false
        let ref = Database.database().reference()
        ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snapshot) in
            if let properties = snapshot.value as? [String : AnyObject]{
                if let peopleWhoLike = properties["peopleWhoLike"] as? [String : AnyObject]{
                    for (id,person) in peopleWhoLike{
                        if person as? String == Auth.auth().currentUser!.uid{
                            ref.child("posts").child(self.postID).child("peopleWhoLike").child(id)
.removeValue(completionBlock: { (error, reff) in
                                if error == nil{
                                    ref.child("posts").child(self.postID).observeSingleEvent(of: 
.value, with: { (snap) in
                                        if let prop = snap.value as? [String : AnyObject]{
                                            if let likes = prop["peopleWhoLike"] as? [String : AnyObject]{
                                                let count = likes.count
                                                self.likeLabel.text = "\(count) Likes"
                                                ref.child("posts").child(self.postID)
.updateChildValues(["likes" : count])
                                            }else{
                                                self.likeLabel.text = "0 Likes"
                                                ref.child("posts").child(self.postID)
.updateChildValues(["likes" : 0])
                                            }
                                        }
                                    })
                                }
                            })
                            self.likeBtn.isHidden = false
                            self.unlikeBtn.isHidden = true
                            self.unlikeBtn.isEnabled = true
                            break
                        }
                    }
                }
            }
        })
        ref.removeAllObservers()
    }
   
  //  @IBAction func backButton(_ sender: Any) {
     //   let tabVC = UIStoryboard(name: "Main", bundle: nil)
// .instantiateViewController(withIdentifier: "NavigationTab") as! UITabBarController
    //    tabVC.selectedIndex = 0
       
   //     self.present(tabVC, animated: true, completion: nil)
       
//   }
   
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
  
      authorLabel.text = authorName
        authorImage.downloadImage(from: authorPic)
        postImage.downloadImage(from: postPic)
        likeLabel.text = likesText
        timeLabel.text = time
    }
   
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        for person in likesCount{
            if person == Auth.auth().currentUser!.uid{
                unlikeBtn.isHidden = false
                likeBtn.isHidden = true
               
                break
            }
        }
    }

}


PostCell:


import UIKit
import Firebase

protocol commentButtonDelegate {
    func commentButtonTapped(at index: IndexPath) 
}

class PostCell: UICollectionViewCell {

    @IBOutlet weak var postImage: UIImageView!
    @IBOutlet weak var authorLabel: UILabel!
    @IBOutlet weak var likeLabel: UILabel!
    @IBOutlet weak var likeBtn: UIButton!
    @IBOutlet weak var unlikeBtn: UIButton!
    @IBOutlet weak var authorImage: UIImageView!
    @IBOutlet weak var commentBtn: UIButton!
     @IBOutlet weak var timeLabel: UILabel!

   
    var postID: String!
     var delegate: commentButtonDelegate!
   
    @IBAction func likePressed(_ sender: Any) {
 
        self.likeBtn.isEnabled = false
        let ref = Database.database().reference()
        let keyToPost = ref.child("posts").childByAutoId().key
       
        ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snapshot) in
            if let post = snapshot.value as? [String : AnyObject]{
             
                let  updateLikes: [String : Any] = ["peopleWhoLike/\(keyToPost!)" :
 Auth.auth().currentUser!.uid]
                ref.child("posts").child(self.postID).updateChildValues(updateLikes, 
withCompletionBlock: { (error, reff) in
                    if error == nil{
                        ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snap) in
                            if let properties = snap.value as? [String : AnyObject]{
                                if let likes = properties["peopleWhoLike"] as? [String : AnyObject]{
                                    let count = likes.count
                                    self.likeLabel.text = "\(count) Likes"
                                    let update = ["likes" : count]
                                    ref.child("posts").child(self.postID).updateChildValues(update)
                                   
                                    self.likeBtn.isHidden = true
                                    self.unlikeBtn.isHidden = false
                                    self.likeBtn.isEnabled = true
             
                                }
                            }
                            })
                    }else{
                        print(post)
                    }
                })
            }
        })
        ref.removeAllObservers()
       
    }
   
    @IBAction func unlikePressed(_ sender: Any) {
  
        self.unlikeBtn.isEnabled = false
        let ref = Database.database().reference()
        ref.child("posts").child(self.postID).observeSingleEvent(of: .value, with: { (snapshot) in
            if let properties = snapshot.value as? [String : AnyObject]{
                if let peopleWhoLike = properties["peopleWhoLike"] as? [String : AnyObject]{
                    for (id,person) in peopleWhoLike{
                        if person as? String == Auth.auth().currentUser!.uid{
                            ref.child("posts").child(self.postID).child("peopleWhoLike").child(id)
.removeValue(completionBlock: { (error, reff) in
                                if error == nil{
                                    ref.child("posts").child(self.postID).observeSingleEvent(of: 
.value, with: { (snap) in
                                        if let prop = snap.value as? [String : AnyObject]{
                                            if let likes = prop["peopleWhoLike"] as? [String : AnyObject]{
                                                let count = likes.count
                                                self.likeLabel.text = "\(count) Likes"
                                                ref.child("posts").child(self.postID)
.updateChildValues(["likes" : count])
                                            }else{
                                                self.likeLabel.text = "0 Likes"
                                                ref.child("posts").child(self.postID)
.updateChildValues(["likes" : 0])
                                            }
                                        }
                                        })
                                }
                            })
                            self.likeBtn.isHidden = false
                            self.unlikeBtn.isHidden = true
                            self.unlikeBtn.isEnabled = true
                           
                            break
                        }
                    }
                }
            }
            })
        ref.removeAllObservers()
       
    }
   
    var indexPath: IndexPath!
   

    @IBAction func commentBtn(_ sender: UIButton) {
        self.delegate?.commentButtonTapped(at: indexPath)
    }
   
    var userID: String!
}

I'm a bit lost in your code:


PostCommentController is VC1

NewsViewController is VC2


So

    @IBAction func unwindToViewController1(_ sender: UIStoryboardSegue) {
        print("I just unwind")
    }

must be in VC1 PostCommentController, not in VC2 NewsViewController


In VC2, you have

    func commentButtonTapped(at index: IndexPath) {
     
        let vc = storyboard?.instantiateViewController(withIdentifier: "PostCommentController") as? PostCommentController
        self.present(vc!, animated: true, completion: nil)

So, you instanciate a new VC1 !


So could you also explai in simple words the logic:

- in PostCommentController: you have several posts ? Each with a like button ? What actions are possible for user ?

- in NewsViewController, what do you have ? What actions are possible for user ?

So what should I do instead of instanciate?


in PostCommentController it's the post itself after you press on the index row.

in NewsViewController you have a several posts, you have a like\unlike button,

and a comment button which is:


func commentButtonTapped(at index: IndexPath)


and it takes you to PostCommentController,

there you have the same functions as like\unlike button, and a comment section,

which is irrelevent for now.

So what should I do instead of instanciate?


Do you understand why it is a problem with the drawing I posted ?

You should try dismissing the NewsViewController controller instead

TMI below/above. Let's first identify the problem here. You wrote:


"the user has a name called Bill,

.....another view ....change his name to Jack,

when Im going back to the previous view to see his name..."


The issue is what the code understands as "his name". In each view controller there is a local variable that represents "his name". They are different in the different view controllers. When you change that local variable in that second view controller you are not changing that local variable in the first view controller. So your question is really - how do I change the value of a variable in a first view controller from within a second view controller. There are many ways. The best is to use MVC structures and have only one "his name". You can do that with a singleton Model, or just use NSUserDefaults as your Model until you learn how to really follow MVC structure. Set a value for

NSString *hisName = [[NSUserDefaults standardUserDefaults] objectForKey:@"HisName"];

using

[[NSUserDefaults standardUserDefaults] setObject:@"Bill" forKey:@"HisName"];

in any view controller. Then reset it to "Jack" in any other view controller. And if you use that Model value for "HisName" as a local variable in any view controller then set the local variable each time the view controller does a viewWillAppear.