Как инициировать представление выноски MKAnnotationView, не касаясь контакта?

Я впервые использовал решение Xilexio, но оно было медленным. Я в конечном итоге с помощью тегов. Вот мой код и приведенный в качестве примера.

@property (nonatomic) NSInteger currentFormField;

typedef NS_ENUM(NSInteger, IOUFormField) {
    IOUFormFieldName,
    IOUFormFieldAmount,
    IOUFormFieldDescription,
    IOUFormFieldDate
};

...

self.nameField.tag = IOUFormFieldName;
self.amountField.tag = IOUFormFieldAmount;
self.descriptionField.tag = IOUFormFieldDescription;
self.dateField.tag = IOUFormFieldDate;

-(void)keyboardWillShow:(NSNotification *)notification {
    // Move the scroll view to a position where the user can see the top and bottom form fields
    // For example, if the user is on the description field, they should be able to see the date field and the amount field.

    // The keyboard rect value comes as a NSValue * (a wrapped NSRect) with origin and size.
    // The origin is using screen coordinates which is pixel based so don't use it.
    // Use the size. Seems like it is density based.
    CGFloat viewableScreenHeight = self.view.frame.size.height - keyboardFrameBeginRect.size.height;

    // When the user is on a form field, get the current form field y position to where the scroll view should move to
    CGFloat currentFormFieldYPosition = 0;
    switch (self.currentFormField) {
        case IOUFormFieldName:
        {
            currentFormFieldYPosition = self.nameField.frame.origin.y;

            // If the scroll view is at the bottom and the user taps on the name field, move the scroll view to the top.
            // This is so that users can see the give/get segments.
            [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];

            break;
        }
        case IOUFormFieldAmount:
        {
            currentFormFieldYPosition = self.amountField.frame.origin.y;
            break;
        }
        case IOUFormFieldDescription:
        {
            currentFormFieldYPosition = self.descriptionField.frame.origin.y;
            break;
        }
        case IOUFormFieldDate:
        {
            currentFormFieldYPosition = self.dateField.frame.origin.y;
            break;
        }
        default:
            break;
    }

    // I want the current form field y position to be 100dp from the keyboard y position.
    // 50dp for the current form field to be visible and another 50dp for the next form field so users can see it.
    CGFloat leftoverTopHeight = viewableScreenHeight - 100;

    // If the current form field y position is greater than the left over top height, that means that the current form field is hidden
    // We make the calculations and then move the scroll view to the right position
    if (currentFormFieldYPosition > leftoverTopHeight) {
        CGFloat movedScreenPosition = currentFormFieldYPosition - leftoverTopHeight;
        [self.scrollView setContentOffset:CGPointMake(0, movedScreenPosition) animated:YES];
    }   
}

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    switch (textField.tag) {
        case IOUFormFieldName:
            self.currentFormField = IOUFormFieldName;
            break;
        case IOUFormFieldAmount:
            self.currentFormField = IOUFormFieldAmount;
            break;
        case IOUFormFieldDescription:
            self.currentFormField = IOUFormFieldDescription;
            break;
        case IOUFormFieldDate:
            self.currentFormField = IOUFormFieldDate;
        default:
            break;
    }

    return true;
}

Дайте мне знать, если у вас есть какие-либо вопросы, и я уточню. Обратите внимание, что комментарии для меня. Также обратите внимание, что некоторые коды или опущены для краткости.

74
задан Atulkumar V. Jain 22 May 2012 в 12:54
поделиться

6 ответов

Хорошо, вот решение этой проблемы.

Для отображения выноски используйте MKMapView метод selectAnnotation: animated .

34
ответ дан 24 November 2019 в 11:51
поделиться

У меня это не работает. Я подозреваю, что это ошибка в API MapKit.

См. Эту ссылку, чтобы получить подробную информацию о том, для кого это не работает: http://www.iphonedevsdk.com/forum/iphone-sdk-development/19740-trigger-mkannotationview-callout-bubble.html#post110447

--edit--

Ладно после того, как накрутил это какое-то время вот что мне удалось заставить работать:

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}

Обратите внимание, это требует реализации - (BOOL) isEqual: (id) anObject для вашего класса, реализующего протокол MKAnnotation.

9
ответ дан 24 November 2019 в 11:51
поделиться

Но есть уловка, чтобы заставить решение benvolioT работать, код

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}

должен вызываться из - (void) mapViewDidFinishLoadingMap: (MKMapView *) mapView и нигде больше.

Последовательность, в которой различные методы, такие как viewWillAppear , viewDidAppear из UIViewController и - (void) mapViewDidFinishLoading *) mapView вызывается по-разному между первой загрузкой карты с одним конкретным местоположением и последующими разами, когда карта отображается с тем же местоположением. Это немного сложно.

62
ответ дан 24 November 2019 в 11:51
поделиться

If you just want to open the callout for the last annotation you added, try this, works for me.

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];

6
ответ дан 24 November 2019 в 11:51
поделиться

из-за чего-то вроде кода, показанного Benvoliot, что я подозреваю, что в системе, когда я использовал Sealannotation: Анимация: Метод, он не послужил выношению, я догадался, что причина была, потому что она уже выбрана, и избегало попросить MAPVIVE перерисовать вызыву на карте, используя название аннотации и субтитров.

Итак, решение было просто отменито тому, чтобы сначала было отменито, и повторно выбрать его.

E.g: Во-первых, мне нужно было сделать это в сенсорном методе Apple (I.e. Как перетащить AnnotationView), чтобы скрыть вызывую. (Просто используя Annotation.canshowannotation = ни один не работает, поскольку я подозреваю, что ему нужно перерисовать. Деселектанотайтонет вызывает необходимое действие. Также отменившись в одиночку не делал этого трюка, выяснил только один раз и получил перерисовку. Это Был подсказкой, который он получил автоматически повторно).

annotationView.canShowAnnotation = NO;
[mapView deselectAnnotation:annotation animated:YES];

Затем, просто используя код ниже в затронутом способе, не вернул вызываемость (аннотация была автоматически выбрана системой к тому времени, и, по-видимому, предварительно перерисование вызовов никогда не оказывает occrrs):

annotationView.canShowAnnotation = YES;
[mapView selectAnnotation:annotation animated:YES];

решение было :

annotationView.canShowAnnotation = YES;
[mapView deselectAnnotation:annotation animated:YES];
[mapView selectAnnotation:annotation animated:YES];

Это просто выкупило отзыву, по-видимому, повторно инициировало процесс перерисования вызове MapView.

Строго говоря, я должен определить, является ли аннотация текущей аннотацией или нет (выбрано, что я знаю, это есть) и независимо от того, на самом деле вызывается или нет (которые я не знаю) и решите перерисовать его соответственно , это было бы лучше. Я, однако, еще не нашел метод обнаружения выносов, и пытался сделать это, сам всего немного ненужным на этом этапе.

3
ответ дан 24 November 2019 в 11:51
поделиться

Ответ Стива Ши ясно дал мне понять, что selectAnnotation необходимо вызывать из метода mapViewDidFinishLoadingMap. К сожалению, я не могу проголосовать, но хочу поблагодарить.

1
ответ дан 24 November 2019 в 11:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: