kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
 VK.Dev
VK.Dev
Вопрос

Изменение заголовка диалогового окна предупреждения JavaScript в iOS

Можно ли изменить заголовок JavaScript-оповещения в UIWebview в iPhone?

35 2012-05-21T07:55:10+00:00 7
Robert Karl
Robert Karl
Редактировал вопрос 13-го мая 2013 в 6:53
Программирование
javascript
ios
uiwebview
Решение / Ответ
 twk
twk
28-го января 2013 в 3:13
2013-01-28T15:13:46+00:00
Дополнительно
Источник
Редактировать
#16237271

В принципе, вы не можете изменить заголовок, но недавно я нашел способ показать диалог предупреждения без заголовка.

var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", 'data:text/plain,');
document.documentElement.appendChild(iframe);
window.frames[0].window.alert('hello');
iframe.parentNode.removeChild(iframe);
57
0
 TomSwift
TomSwift
29-го мая 2013 в 1:16
2013-05-29T01:16:33+00:00
Дополнительно
Источник
Редактировать
#16237273

Я представляю три отдельных решения этой проблемы. Лучшее решение для производства кода описанного @Х. Мартин-мой единственный дополнение к это конкретный пример, показывающий, как это реализовать.

Другие мои решения зависят от незарегистрированных поведения UIWebView, но Дон'т требует каких-либо изменений в содержание и JS.

Решения 1: Вот конкретный пример, демонстрирующий технику, выдвинутые @Мартин х. Это, вероятно, лучшее решение, а не полагаться на UIWebView / UIAlertView недокументированное поведение.

@interface TSViewController () <UIWebViewDelegate>
@end

@implementation TSViewController

- (UIWebView*) webView
{
    return (UIWebView*) self.view;
}

- (void) loadView
{
    UIWebView* wv = [[UIWebView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
    wv.delegate = self;
    wv.scalesPageToFit = YES;

    self.view = wv;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    [self.webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: @"http://www.craigslist.org"]]];
}

- (void) webViewDidFinishLoad: (UIWebView *) webView
{
    // inject some js to re-map window.alert()
    // ideally just do this in the html/js itself if you have control of that.
    NSString* js = @"window.alert = function(message) { window.location = \"http://action/alert?message=\" + message; }";
    [webView stringByEvaluatingJavaScriptFromString: js];

    // trigger an alert.  for demonstration only:
    [webView stringByEvaluatingJavaScriptFromString: @"alert('hello, world');" ];
}

- (BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL* url = request.URL;

    // look for our custom action to come through:
    if ( [url.host isEqualToString: @"action"] && [url.path isEqualToString: @"/alert"] )
    {
        // parse out the message
        NSString* message = [[[[url query] componentsSeparatedByString: @"="] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        // show our alert
        UIAlertView* av = [[UIAlertView alloc] initWithTitle: @"My Custom Title"
                                                     message: message
                                                    delegate: nil
                                           cancelButtonTitle: @"OK"
                                           otherButtonTitles: nil];

        [av show];

        return NO;
    }
    return YES;
}

Решение 2: Во-первых, позвольте мне сказать, что я никогда бы лично использовать следующее решение в производственном коде. Лучший способ для достижения этой функции является делать то, что @Мартин ч показывает в своем ответе, или, возможно, что @моя жена предполагает, если пустое название на самом деле что то нужное. Если вы Don'т контролировать себя веб-контента, возможно, вы могли бы впрыскивают @Мартин ч's код после того, как контент был загружен.

Что сказал, это иначе достижимо, если мы сделаем некоторые предположения. Во-первых, что предупреждение на JavaScript () метод действительно соотносится с реальным UIAlertView. (На самом деле это делает!) Во-вторых, что мы можем придумать какой-то механизм, чтобы заметить их предупреждения ()источников UIAlertView из других приложений-источниковUIAlertViews`. (Мы можем!)

Мой подход заключается в мошенничество в UIAlertView. Я знаю - группирующее хреново и еще много всяких недостатков. Я Дон'т мошенничество в производственные приложения, если я могу помочь ему. Но для этого научный проект, мы'ре собираюсь мошенничество в UIAlertView setDelegate: метод.

Я обнаружил, что 1) UIWebView создаст UIAlertView для отображения JavaScript оповещения, и 2)UIAlertViewзаголовок находится перед делегировать UIAlertView набор. По группирующееUIAlertView setDelegate:с мой собственный способ я могу сделать две вещи: 1) я могу определить, что UIAlertView будет сдан на имениUIWebView` (просто проверить делегат...) и 2) у меня есть возможность поменять название перед alertview отображается.

Вы можете спросить "Почему не просто мошенничество UIAlertview -показать способ?&и" Это было бы здорово, но в мои эксперименты, я обнаружил, что UIWebView не ссылаться на "шоу". Это надо называть каким-то иным внутренним методом, и я не'т дальнейшего расследования.

Мое решение реализует категорию на UIAlertView, который добавляет пару методов класса. В основном вы регистрируете UIWebView с помощью этих методов, и укажите название замены, которые будут использоваться. Кроме того, вы можете предоставить блок обратного вызова, которая возвращает заголовок при вызове.

Я использовал в iOS6 NSMapTable класс, чтобы сохранить набор UIWebView до звания сопоставления, где UIWebView является слабым ключом. Таким образом, я не'Т когда-нибудь придется отменить мой UIWebView и все отмылась. Таким образом, текущая реализация в iOS6-только.

Здесь'ы код, показанный в основной контроллер представления:

#import <objc/runtime.h>

typedef NSString*(^TSAlertTitleBlock)(UIWebView* webView, NSString* defaultTitle );

@interface UIAlertView (TS)
@end

@implementation UIAlertView (TS)

NSMapTable* g_webViewMapTable;

+ (void) registerWebView: (UIWebView*) webView alertTitleStringOrBlock: (id) stringOrBlock
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        g_webViewMapTable = [NSMapTable weakToStrongObjectsMapTable];

        // $wizzle
        Method originalMethod = class_getInstanceMethod(self, @selector(setDelegate:));
        Method overrideMethod = class_getInstanceMethod(self, @selector(setDelegate_ts:));
        method_exchangeImplementations(originalMethod, overrideMethod);
    });

    [g_webViewMapTable setObject: [stringOrBlock copy] forKey: webView];
}

+ (void) registerWebView: (UIWebView*) webView alertTitle: (NSString*) title
{
    [self registerWebView: webView alertTitleStringOrBlock: title];
}

+ (void) registerWebView: (UIWebView*) webView alertTitleBlock: (TSAlertTitleBlock) alertTitleBlock
{
    [self registerWebView: webView alertTitleStringOrBlock: alertTitleBlock];
}

- (void) setDelegate_ts: (id) delegate
{
    // call the original implementation
    [self setDelegate_ts: delegate];

    // oooh - is a UIWebView asking for this UIAlertView????
    if ( [delegate isKindOfClass: [UIWebView class]] )
    {
        // see if we've registered a title/title-block
        for ( UIWebView* wv in g_webViewMapTable.keyEnumerator )
        {
            if ( wv != delegate)
                continue;

            id stringOrBlock = [g_webViewMapTable objectForKey: wv];

            if ( [stringOrBlock isKindOfClass: NSClassFromString( @"NSBlock" )] )
            {
                stringOrBlock = ((TSAlertTitleBlock)stringOrBlock)( wv, self.title );
            }

            NSParameterAssert( [stringOrBlock isKindOfClass: [NSString class]] );

            [self setTitle: stringOrBlock];
            break;
        }
    }
}

@end

@interface TSViewController () <UIWebViewDelegate>
@end

@implementation TSViewController

- (UIWebView*) webView
{
    return (UIWebView*) self.view;
}

- (void) loadView
{
    UIWebView* wv = [[UIWebView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
    wv.delegate = self;
    wv.scalesPageToFit = YES;

    self.view = wv;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    // method 1: bind a title to a webview:
    [UIAlertView registerWebView: self.webView alertTitle: nil];

    /*
    // method 2: return a title each time it's needed:
    [UIAlertView registerWebView: self.webView
                 alertTitleBlock: ^NSString *(UIWebView *webView, NSString* defaultTitle) {

                     return @"Custom Title";
    }];
     */

    [self.webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: @"http://www.craigslist.org"]]];
}

- (void) webViewDidFinishLoad: (UIWebView *) webView
{
    // trigger an alert
    [webView stringByEvaluatingJavaScriptFromString: @"alert('hello, world');" ];
}

@end

Решения 3: поразмыслив, здесь'ы более простой технике, чем я изначально описал в растворе 2. Это еще зависит от недокументированных факт, что JavaScript оповещения осуществляется с помощью UIAlertView, что был делегатом установить в поиске UIWebView. Для этого решения, просто подкласс UIWebView и реализовать свой собственный метод делегата для UIAlertView willPresentAlertView:, и когда он призывал, сбросьте название, чтобы все, что вы пожелаете.

@interface TSWebView : UIWebView
@end

@implementation TSWebView

- (void) willPresentAlertView:(UIAlertView *)alertView
{
    if ( [self.superclass instancesRespondToSelector: @selector( willPresentAlertView:) ])
    {
        [super performSelector: @selector( willPresentAlertView:) withObject: alertView];
    }

    alertView.title = @"My Custom Title";
}

@end

@interface TSViewController () <UIWebViewDelegate>
@end

@implementation TSViewController

- (UIWebView*) webView
{
    return (UIWebView*) self.view;
}

- (void) loadView
{
    UIWebView* wv = [[TSWebView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)];
    wv.delegate = self;
    wv.scalesPageToFit = YES;

    self.view = wv;
}

- (void) viewDidLoad
{
    [super viewDidLoad];

    [self.webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: @"http://www.craigslist.org"]]];
}

- (void) webViewDidFinishLoad: (UIWebView *) webView
{
    // trigger an alert
    [webView stringByEvaluatingJavaScriptFromString: @"alert('hello, world');" ];
}

@end
 Community
Community
Редактировал ответ 23-го мая 2017 в 11:46
15
0
 Gruntcakes
Gruntcakes
24-го мая 2012 в 2:25
2012-05-24T14:25:33+00:00
Дополнительно
Источник
Редактировать
#16237270

Нет, вы не можете сделать это в оповещении Javascript.

Но если Javascript ваш, то вместо вызова оповещения вы можете вызвать функцию, которая вызовет Objective C и вызовет родное оповещение iOS.

Если Javascript не ваш, то с помощью UIWebView вы можете внедрить некоторый Javascript, чтобы переопределить поведение по умолчанию и изменить его для вызова родного оповещения iOS, т.е. что-то вроде этого

window.alert = function(message) {
  window.location = "myScheme://" + message"
};

Затем найдите myScheme и извлеките сообщение в UIWebView's shouldStartLoadWithRequest

Вот'стандартный метод вызова Objective-C из Javascript

https://stackoverflow.com/questions/1662473/how-to-call-objective-c-from-javascript

 Community
Community
Редактировал ответ 23-го мая 2017 в 11:53
10
0
Myrne Stol
Myrne Stol
25-го мая 2013 в 5:32
2013-05-25T17:32:34+00:00
Дополнительно
Источник
Редактировать
#16237272

Если уж на то пошло, Phonegap/Cordova предлагает функцию navigator.notification.alert. Она позволяет указать пользовательский заголовок.

4
0
 ShervinJam
ShervinJam
1-го марта 2016 в 7:43
2016-03-01T19:43:09+00:00
Дополнительно
Источник
Редактировать
#16237276

Просто сделать класс для UIWebView и сделать willPresentAlertView функции (alertView: UIAlertView) в нем. После этого сеть alertView.заголовок = "и ваше название на&quot ФАВ; и это делается.

    import UIKit

class webviewClass: UIWebView {

func willPresentAlertView(alertView: UIAlertView) {

    alertView.title = "my custum title"
}

}

После этого, когда когда-либо предупреждения или подтверждения и... показали, свое индивидуальное название будет показано.

 Mogsdad
Mogsdad
Редактировал ответ 1-го марта 2016 в 8:00
1
0
 socca1157
socca1157
25-го февраля 2014 в 6:05
2014-02-25T06:05:05+00:00
Дополнительно
Источник
Редактировать
#16237274

Осознав @TWK по написал, Я просто переписать функцию оповещения. Отлично работает на iOS7.

function alert(words){
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", 'data:text/plain,');
document.documentElement.appendChild(iframe);
window.frames[0].window.alert(words);
iframe.parentNode.removeChild(iframe);
}
0
0
 Aladin
Aladin
5-го октября 2015 в 4:57
2015-10-05T16:57:13+00:00
Дополнительно
Источник
Редактировать
#16237275

Использовать Cordova-плагин-диалоги. Он позволяет создавать собственные диалоговые окна.

Ниже код будет создавать собственные оповещения:

navigator.notification.alert(message, alertCallback, [title], [buttonName])
 sammyukavi
sammyukavi
Редактировал ответ 5-го октября 2015 в 5:24
0
0
Похожие сообщества 17
JavaScript Jobs — чат
JavaScript Jobs — чат
26 291 пользователей
JavaScript Jobs — чат для поиска работы и людей Правила оформления: @telegram-ru/r1WQe5F1m" rel="nofollow noopener noreferrer" class="text-blue hover:text-black link" target="_blank">https://teletype.in/@telegram-ru/r1WQe5F1m См. также: @mobile_jobs, @devops_jobs, @nodejs_jobs, @react_js, @angular_ru, @js_ru
Открыть telegram
Mobile Dev Jobs — вакансии и аналитика
Mobile Dev Jobs — вакансии и аналитика
19 732 пользователей
Публикуем вакансии и запросы на поиск работы по направлению iOS, Android, Xamarin и т.д. Размещение бесплатное. 📌 ВАЖНО: Правила публикации и правила канала: 📌 Ссылка – https://telegra.ph/Pravila-oformleniya-vakansij-i-rezyume-12-10
Открыть telegram
JavaScript Noobs — сообщество новичков
JavaScript Noobs — сообщество новичков
9 470 пользователей
Помогаем друг другу разбираться с JS Правила: @js_noobs_ru/rules" rel="nofollow noopener noreferrer" class="text-blue hover:text-black link" target="_blank">https://teletype.in/@js_noobs_ru/rules Другие полезные чаты — https://github.com/goq/telegram-list или https://rudevs.network/ByKT2JwWQ
Открыть telegram
JavaScript — русскоговорящее сообщество
JavaScript — русскоговорящее сообщество
7 714 пользователей
Рекомендуем сразу отключить уведомления Правила: https://git.io/JycBd См. также: @js_noobs_ru, @nodejs_ru, @ts_cool, @react_js, @electron_cool Вакансии и поиск работы: @javascript_jobs
Открыть telegram
iOS Developers — русскоговорящее сообщество
iOS Developers — русскоговорящее сообщество
6 339 пользователей
Общаемся на темы, посвященным iOS-разработке, Swift, Objective-C и т.д. См. также: @android_ru, @macdev_ru, @macos_ru Вакансии и поиск работы: @mobile_jobs Правила чата: https://telegra.ph/Pravila-ios-ru-04-16 Логотип авторства @master_branch спасибо ему
Открыть telegram
JavaScript.Ninja
JavaScript.Ninja
3 822 пользователей
Правила поведения проекта https://telegra.ph/Kodeks-povedeniya-proekta-JavaScriptNinja-12-15
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Ilya Smirnov
Зарегистрирован 5 дней назад
2
Денис Васьков
Зарегистрирован 1 неделю назад
3
Dima Patrushev
Зарегистрирован 1 неделю назад
4
sirojidddin otaboyev
Зарегистрирован 2 недели назад
5
Елена Гайдамамакинат
Зарегистрирован 2 недели назад
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией