user3126427 user3126427 - 12 days ago 8
iOS Question

Swift MapView Doesn't Retain Latest Shift when Populating Xib Image Element

I have an Xcode project with a mapView. I load my friend (Kevin) from this array:

myProfiles.append(UserClass
(locationLatitude:44.067, locationLongitude:-88.296,
id:1,username: "Kevin"
)
)


I have a customAnnotation that displays my friend on the map. My friend annotation is at the bottom of the map. So, when I click on the annotation the mapView should push up by 203 spaces and remain there.

// triggered when the user selects an annotation. We are clicking on Kevin
func mapView(_ mapView: MKMapView, didSelect annotationView: MKAnnotationView)
{
print("before setting map")
let adjustedBy: CGFloat = 203.0
self.mapView.frame.origin.y = self.mapView.frame.origin.y - adjustedBy
self.populateSelectedProfile()
}

func populateSelectedProfile() {
DispatchQueue.main.async {
// the tag 1000 is for the first user in array (username: Kevin)
if let userXib = self.view.viewWithTag(1000) as? User {
print("setting up user")
userXib.isHidden = false
userXib.userImageView.image = UIImage(named: "user")
}
}
}


The populateSelectedProfile will start populating the xib with the friend's image (ImageView is created in the builder):

@IBOutlet weak var userImageView: UIImageView!


But what happens is that the map after the pushing to the top, it goes down right after the populating of the imageView. You can see this behavior if you place a breaking point at the print line:

print("setting up user")


Why does the mapView shift down again?

Please Note: I don't care about displaying the image. I know how to do it. My issue is with the mapView coming down again.

Answer

You need to let the xib finish loading first via completion handler and then you do your animation part. I think loading the xib from memory resets the mapview to its original state

// triggered when the user selects an annotation. We are clicking on Kevin
func mapView(_ mapView: MKMapView, didSelect annotationView: MKAnnotationView)
{
    print("before setting map")
    let adjustedBy: CGFloat = 203.0
    self.mapView.frame.origin.y = self.mapView.frame.origin.y - adjustedBy
    self.populateSelectedProfile { finished in
        DispatchQueue.main.async {
            let adjustedBy: CGFloat = 203.0
            self.mapView.frame.origin.y = self.mapView.frame.origin.y - adjustedBy
        }
    }
}

func addUserXib(completion: @escaping ((_ finished: Bool) -> Void)) {
    if let userXib = Bundle.main.loadNibNamed("User", owner: self, options: nil)?[0] as? User
    {
        userXib.tag = 1000
        userXib.frame = CGRect(x: width, y: 0, width: width, height: height * (3 / 8))
        userXib.isHidden = true
        self.view.addSubview(userXib)
    }
}