web-dev-qa-db-ja.com

UIWebView Shadowを削除しますか?

UIWebViewウィンドウに配置された影を削除できるかどうか誰かが知っていますか?

例: http://uploadingit.com/files/1173105_olub5/shadow.png

可能であれば、どのようにそれを行いますか?

ありがとう

31
dlewis23

これは、「ニコライオキアミ」ソリューションのよりクリーンな代替手段です。これにより、UIWebView内のUIImageViewのみが非表示になり、UIWebBrowserViewは非表示になりません。

for (UIView *view in [[[webView subviews] objectAtIndex:0] subviews]) { 
  if ([view isKindOfClass:[UIImageView class]]) view.hidden = YES;
}   

ありがとうジェームズ

71
jodm

Appleがサブビューの数を変更するとクラッシュする可能性があるため、小さなforループは非常に危険です。

このようにして、何かが変更されても少なくともクラッシュしません。

if ([[webView subviews] count] > 0)
{
    for (UIView* shadowView in [[[webView subviews] objectAtIndex:0] subviews])
    {
        [shadowView setHidden:YES];
    }

    // unhide the last view so it is visible again because it has the content
    [[[[[webView subviews] objectAtIndex:0] subviews] lastObject] setHidden:NO];
}
14
denis2342

BOOL値をとるセレクターsetAllowsRubberBanding:を持つプライベートメソッドがあります。 NOを渡した場合、コンテンツ領域の上部または下部を超えてWebビューをスクロールすることはできませんが、通常どおりWebビューをスクロールすることはできます。残念ながら、このメソッドはISプライベートであり、アプリを使用するとストアへのアクセスが許可されない可能性があります。

ただし、Objective-Cのランタイムの動的な性質を使用して、メソッドの実装を抽出し、作成した別のセレクターにバインドすることもできます。

それでも、このメソッドはプライベートであり、OSの将来のバージョンには存在しなくなる可能性があります。それでも試してみたい場合は、setAllowsRubberBanding:メソッドの実装を抽出して呼び出すサンプルコードを次に示します。

static inline void ShhhDoNotTellAppleAboutThis (UIWebView *webview)
{
    const char *hax3d = "frgNyybjfEhooreOnaqvat";
    char appleSelName[24];

    for (int i = 0; i < 22; ++i)
    {
        char c = hax3d[i];
        appleSelName[i] = (c >= 'a' && c <= 'z') ? ((c - 'a' + 13) % 26) + 'a' : ((c - 'A' + 13) % 26) + 'A';
    }
    appleSelName[22] = ':';
    appleSelName[23] = 0;

    SEL appleSEL = sel_getUid(appleSelName);

    UIScrollView *scrollView = (UIScrollView *)[webview.subviews objectAtIndex:0];
    Class cls = [scrollView class];
    if (class_respondsToSelector(cls, appleSEL) == NO)
    {
        return;
    }

    IMP func = class_getMethodImplementation(cls, appleSEL);
    func(scrollView, appleSEL, NO);
}

このコードを使用してアプリをAppStoreに送信することを選択した場合、これはおそらくAppleの静的アナライザーによって検出される可能性があることに注意してください。

5
PfhorSlayer

これがSwift iOS 9のUIWebViewの影を取り除く関数です。これは、SOで見たどの代替手段よりも安全です。これはAppleドキュメントにあり、ビュー全体またはビューの他のプロパティを非表示にするのではなく、特にシャドウプロパティを変更します)。

func removeShadow(webView: UIWebView) {
    for subview:UIView in webView.scrollView.subviews {
        subview.layer.shadowOpacity = 0
        for subsubview in subview.subviews {
            subsubview.layer.shadowOpacity = 0
        }
    }
}

UIViewdocumentation )のsubviewsプロパティにはいつでもアクセスできます。すべてのUIViewには、layerドキュメント )であるCALayerプロパティがあります。すべてのCALayerにはshadowOpacityドキュメント )があります。

警告:

  1. 状況によっては、サブビューを介してビュー階層をナビゲートする必要がある場合があります。
  2. これは、WebViewControllerのどこにも影が必要ない限り機能します。シャドウを保持するビュー(デフォルトのUIWebViewシャドウ以外)がある場合は、if-checkを追加してそのビューを識別し、そのビューのレイヤーのshadowOpacityをゼロに設定しないでください。
  3. Apple「UIKitおよびその他のシステムフレームワークで宣言された複雑なビューの場合、ビューのサブビューは通常、プライベートと見なされ、いつでも変更される可能性があります。したがって、取得または取得を試みないでください。これらのタイプのシステム提供ビューのサブビューを変更します。変更すると、将来のシステム更新中にコードが破損する可能性があります。」。.つまり、UIWebViewは変更される可能性があるため、これらのサブビューを掘り下げることはお勧めしません。 UIWebViewは影を取り除く唯一の方法であり、これは比較的安全な方法です。
4
devney

これは、プライベートAPIを使用せずに実行できます。あなたがする必要があるのは、その中に影がある各UIImageViewを隠すことです。コードは次のとおりです。

for (int x = 0; x < 10; ++x) {
    [[[[[webView subviews] objectAtIndex:0] subviews] objectAtIndex:x] setHidden:YES];
}
4
Nikolai Krill

これを試して

func webViewDidFinishLoad(_ webView: UIWebView) {
    for shadowView in self.webView.scrollView.subviews {
        if !shadowView.isKind(of: UIImageView.self) {
            shadowView.subviews[0].layer.shadowColor = UIColor.clear.cgColor
        } else {
            shadowView.layer.shadowColor = UIColor.clear.cgColor
        }
    }
}
2
Berlin Raj

すべてのサブビューをトラバースします。画像の幅が1ピクセルしかないUIImageViewはシャドウ画像であり、非表示にすることができます。

- (void)hideShadows {
    [webview traverseViewsWithBlock:^(UIView *view) {
        UIImageView *imgView = ([view isKindOfClass:[UIImageView class]] ? (UIImageView*)view : nil;
        // image views whose image is 1px wide are shadow images, hide them
        if (imgView && imgView.image.size.width == 1) {
            imgView.hidden = YES;
        }
    }];
}

traverseViewsWithBlockは、次のように表示されます。

- (void)traverseViewsWithBlock:(void (^)(UIView* view))block
{
    block(self);
    for (id subview in self.subviews) {
        [subview traverseViewsWithBlock:block];
    }
}
2
rrrus

スクロールインジケーターを非表示にし、Webビューを透明にする最も簡単な方法 ここ UIWebView

巻物を取り除く。

    for(UIView *view in webView.subviews){   
         if ([view isKindOfClass:[UIScrollView class]]) {  
              UIScrollView *sView = (UIScrollView *)view;  
              //to hide verticalScroller  
              sView.showsVerticalScrollIndicator = NO;
              sView.showsVerticalScrollIndicator = NO;
         }   
    }  
1
damithH

注意する必要があります。スクロールインジケーターもUIImageViewsです。コードを改善しますが、基本的なサブクラス化されたソリューションは次のとおりです。

http://forrst.com/posts/A_tiny_UIWebView_hack_remove_shadows_from_behi-gzH

1
Geri

クラスのプロパティを調べましたが、何も見つかりませんでしたが、2つの「隠蔽」戦略を考えることができます。

1.1。 別のビュー(Webビューの親)を使用して、Webビューの境界をクリップできます。
2.2。 Webビューの上に別のビューを追加して、必要な領域を背景に一致する色で覆うことができます。中央に透明な領域があるuiimageを使用できます。

ちなみに、私はテーブルビューのこの標準的な背景が好きではありません:P、しかしそれを変更することはお尻の痛みになる可能性があります:P

1
user41806

このようなUIWebViewのカテゴリはどうですか?

- (BOOL)showsScrollShadows
{
    for(UIImageView *imageView in [self imageViewsWithShadows])
    {
        if(imageView.hidden)
        {
            return NO;
        }

        break;
    }

    return YES;
}

- (void)setShowsScrollShadows:(BOOL)showsScrollShadows
{
    [[self imageViewsWithShadows] makeObjectsPerformSelector:@selector(setHidden:) withObject:@(!showsScrollShadows)];
}

- (NSArray *)imageViewsWithShadows
{
    NSArray *potentialShadowImageViews = (self.subviews.count > 0) ? [self.subviews[0] subviews] : nil;

    if(potentialShadowImageViews.count > 0)
    {
        NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings)
        {
            return [evaluatedObject isKindOfClass:[UIImageView class]];
        }];

        return [potentialShadowImageViews filteredArrayUsingPredicate:predicate];
    }

    return nil;
}
1
Kukosk

私は周りを見回しましたが、それに関連するものは何も見えません。ビューでマスクしたり、なんらかの方法でクリップしたりする以外に、私が考えることができるのは、すべてのUIWebViewサブビュー(およびサブサブビューなど)をループして、そこに何かが表示されるかどうかを確認することだけです。

0
if (UIDevice.currentDevice.systemVersion.intValue < 7)
    for (UIImageView *imageView in webView.scrollView.subviews)
        if ([imageView isKindOfClass:[UIImageView class]] && imageView.image.size.width == 1)
            imageView.hidden = YES;
0
Friend_LGA

私は間違っているかもしれませんが、影はWebビューをスクロールしたときにのみ表示されると思いますね。その場合、スクロールを防止しますか、それとも本当に影を隠しますか?影を隠すコツはわかりません。スクロールを無効にするには、UserInteractionEnabledをNOに設定します。

0
Unfalkster

UIViewオブジェクトにカテゴリとして再帰メソッドを追加しました。これにより、メソッドの受信ビューのサブビューの深さ優先探索が実行され、見つかったUIImageViewサブクラスが非表示になります。サブビューがない場合はクラッシュしません。 -apply:メソッドは BlocksKit からのものです。この関数を使用しないように書き直すこともできますが、ブロックは受信配列の各要素に並列に適用されるため、かなり高速です。

@implementation UIView (RemoveShadow)

- (void)removeShadow {
  if (self.subviews.count == 0 && [self isKindOfClass:[UIImageView class]]) {
    self.hidden = YES;
  } else if (self.subviews.count > 0) {
    [self.subviews apply:^(id sender) {
      [(UIView *)sender removeShadow];
    }];
  }
}

@end
0
Jacob