Oops. After a day, I realized that I can completely replace the POIs by using the setPointsOfInterest() method.
For example,
func pointOfInterestTemplate(_ pointOfInterestTemplate: CPPointOfInterestTemplate, didChangeMapRegion region: MKCoordinateRegion) {
// sort the list by region.center
self.resortDisplayList(with: region.center)
// generate CPPointOfInterest list and set
pointOfInterestTemplate.setPointsOfInterest(self.buildPlaces(), selectedIndex: NSNotFound)
}