iOS中UIScrollView、UIWebView、UICol

作者: LuisX | 来源:发表于2017-12-04 19:04 被阅读437次
    图文混排

    实现思路

    1. 将文本和图片拼接为HTML代码。
    2. 使用JavaScript添加点击事件。
    3. 使用MagicWebViewWebP提供UIWebView加载webp格式图片支持。
    4. 使用UIWebView加载HTML代码。
    5. 使用UIWebView代理方法,拦截页面发出的请求,获取selectIndex。

    实现效果

    组件 描述 说明
    UIScrollView 根容器 高度自适应(KVO处理UIWebView + UICollectionView高度)
    UIWebView 图文混排展示 加载HTML代码
    UICollectionView 更多推荐展示
    实现效果

    问题汇总

    1、如何实现JavaScript与Objective-C间传值?

    点击Webview中的图片,放大,需要JavaScript和Objective-C传值,获取到具体需要放大哪张图片。

    本方案中,不需要引入WebViewJavascriptBridge,而是通过【控制Webview重定向方法,拦截发出的请求】来实现。

    示例:
    // 每个<img>添加点击事件(window.location.href),其中selectIndex为图片标识
    <img onload="this.onclick = function() {window.location.href = 'selectIndex=' + 0;}" style="clear:both; display:block; margin:auto;" width="100%" src="https://cdn1.showjoy.com/images/5a/5aa6f5c436754174a114abdb0f1581e0.jpg.webp">
    
    // webview发起请求拦截
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
      
        // 获取img标识index
        NSString *url = request.URL.absoluteString;
        NSRange range = [url rangeOfString:@"selectIndex="];
        if (range.location != NSNotFound) {
            NSInteger begin = range.location + range.length;
            NSString *index = [url substringFromIndex:begin];
            NSLog(@"img: %@", index);
            return NO;
        }
        return YES;
      
    }
    

    2、如何实现UIWebView高度自适应?

    UIWebView自适应高度的方案有很多,选择一个较为科学的方式,显得尤为重要。

    本方案中,通过【KVO监听Webview的contentSize】来实现,需要注意KVO的添加、移除,稍有不慎有Crash风险。

    示例:
    // 添加监听
    [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
    
    - (UIWebView *)webView
    {
        if (!_webView) {
            _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
            _webView.delegate = self;
            _webView.scrollView.bounces = NO;
            _webView.scrollView.showsHorizontalScrollIndicator = NO;
            _webView.scrollView.scrollEnabled = NO;
            _webView.scalesPageToFit = YES;
        }
        return _webView;
    }
    
    // 修改webview的frame
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"contentSize"]) {
            CGSize resize = [self.webView sizeThatFits:CGSizeZero];
            self.webView.frame =  CGRectMake(0, 0, CGRectGetWidth(self.frame), resize.height);
        }
    }
    
    // 移除监听
    -(void)dealloc
    {
        [self.webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
    }
    

    3、如何实现UIWebView显示webp格式图片?

    UIWebView、WKWebview本身都不支持webp格式图片,需要额外扩展。

    可以直接访问我的GitHub,下载MagicWebViewWebP,将【MagicWebViewWebP.framework】直接导入工程。

    参考: UIWebView、WKWebView支持WebP图片显示

    示例:
    // 导入头文件
    #import <MagicWebViewWebP/MagicWebViewWebPManager.h>
    
    // 注册 MagicURLProtocol
    [[MagicWebViewWebPManager shareManager] registerMagicURLProtocolWebView:self.webView];
    
    // 销毁 MagicURLProtocol
    -(void)dealloc
    {
        [[MagicWebViewWebPManager shareManager] unregisterMagicURLProtocolWebView:self.webView];
    }
    

    4、如何实现图文混排 + UIKit组件?

    使用UIWebView加载自定义HTML代码的方式,实现图文混排。
    点击图片,放大,function()跳转链接,携带selectIndex标识,通过拦截UIWebView的请求来获取selectIndex标识。

    通过KVO获取到WebView高度,重新设置webView.frame,collectionView.frame,scrollView.contentSize

    本方案中,图文混排+UIKit组件,具体逻辑如下:

    5、如何自定义HTML代码?

    本方案中,以纯图片为例,处理后的HTML如下:

    <html>
    <head>
    </head>
    <body>
        <div class="img-box">
            <img onload="this.onclick = function() {window.location.href = 'selectIndex=' + 0;}" style="clear:both; display:block; margin:auto;" width="100%" src="https://cdn1.showjoy.com/images/5a/5aa6f5c436754174a114abdb0f1581e0.jpg.webp">
        </div>
        <div class="img-box">
            <img onload="this.onclick = function() {window.location.href = 'selectIndex=' + 1;}" style="clear:both; display:block; margin:auto;" width="100%" src="https://cdn1.showjoy.com/images/d8/d8756f54d7524afba4939e5fab9754d6.jpg.webp">
        </div>
        ......
    </body>
    </html>
    

    6、如何实现并发执行多个网络请求,统一处理?

    本方案中,利用GCD创建队列组,提交多个任务到队列组,多个任务同时执行,监听队列组执行完毕,在主线程刷新UI。

    注意: dispatch_group_enter() 、 dispatch_group_leave()将队列组中的任务未执行完毕的任务数目加减1(两个函数要配合使用)

    参考: 玩转GCD

    示例:
    - (void)exampleMoreNetwork{
        
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t serialQueue = dispatch_queue_create("magic_gcd_group", DISPATCH_QUEUE_SERIAL);
        
        // 网络请求1
        dispatch_group_enter(group);
        dispatch_group_async(group, serialQueue, ^{
            [[MagicNetworkManager shareManager] GET:@"网络请求1" Parameters:nil Success:^(NSURLResponse *response, id responseObject) {
                dispatch_group_leave(group);
            } Failure:^(NSURLResponse *response, id error) {
                dispatch_group_leave(group);
            }];
        });
        
        // 网络请求2
        dispatch_group_enter(group);
        dispatch_group_async(group, serialQueue, ^{
            [[MagicNetworkManager shareManager] GET:@"网络请求2" Parameters:nil Success:^(NSURLResponse *response, id responseObject) {
                dispatch_group_leave(group);
            } Failure:^(NSURLResponse *response, id error) {
                dispatch_group_leave(group);
            }];
        });
        
        // 所有网络请求结束
        dispatch_group_notify(group, serialQueue, ^{
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                dispatch_async(dispatch_get_main_queue(), ^{
                    // 主线程刷新UI
                });
            });
        });
        
    }
    

    图文混排——核心

    目录结构

    实现代理方法,放大图片,跳转商品,置顶。
    实现针对showjoy.com域名,图片url拼接.webp。
    实现UIScrollView作为根容器,自适应内容高度。
    实现UIWebView支持webp格式图片。
    实现自定义HTML代码,图片居中,window.location.href事件传递selectIndex,UIWebView代理拦截selectIndex。
    通过HTML,JavaScript,还可以实现更多功能。。。。。。

    ProductLoadMorePicTextView.h
    #import <UIKit/UIKit.h>
    #import "ProductDetailModel.h"
    #import "ProductLoadMorePicTextModel.h"
    
    @protocol ProductLoadMorePicTextViewDelegate <NSObject>
    - (void)productLoadMorePicTextViewZoomImageWithIndex:(NSInteger)index;
    - (void)productLoadMorePicTextViewPushProductWithSkuId:(NSString *)skuId;
    - (void)productLoadMorePicTextViewGoTop;
    @end
    
    @interface ProductLoadMorePicTextView : UIView
    @property (nonatomic, weak) id <ProductLoadMorePicTextViewDelegate> delegate;
    - (instancetype)initWithFrame:(CGRect)frame productDetailModel:(ProductDetailModel *)productDetailModel picTextModel:(ProductLoadMorePicTextModel *)picTextModel;
    - (void)reload;
    @end
    
    ProductLoadMorePicTextView.m
    #import "ProductLoadMorePicTextView.h"
    #import "ProductLoadMorePicTextCollectionViewCell.h"
    #import "MagicScrollPageRefreshHeader.h"
    #import <MagicWebViewWebP/MagicWebViewWebPManager.h>
    
    static const CGFloat recommendViewHeight = 170.0;
    static const CGFloat recommendViewSpace = 10.0;
    static const CGFloat recommendItemWidth = 105.0;
    static const CGFloat recommendItemSpace = 5.0;
    static const CGFloat recommendTitleHeight = 40.0;
    
    @interface ProductLoadMorePicTextView ()<UIWebViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate>
    @property (nonatomic, strong) UIScrollView *scrollView;
    @property (nonatomic, strong) UIWebView *webView;
    @property (nonatomic, strong) UICollectionView *collectionView;
    @property (nonatomic, strong) UILabel *recommendLabel;
    @property (nonatomic, strong) NSMutableArray *recommendDataArray;
    @property (nonatomic, strong) NSMutableArray *picTextDataArray;
    @end
    
    @implementation ProductLoadMorePicTextView
    
    - (instancetype)initWithFrame:(CGRect)frame productDetailModel:(ProductDetailModel *)productDetailModel picTextModel:(ProductLoadMorePicTextModel *)picTextModel
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.recommendDataArray = [NSMutableArray arrayWithArray:productDetailModel.recommend];
            self.picTextDataArray = [NSMutableArray arrayWithArray:picTextModel.itemPic.packageImages];
            [self createSubViewsWithPicTextModel:picTextModel];
        }
        return self;
    }
    
    - (void)createSubViewsWithPicTextModel:(ProductLoadMorePicTextModel *)picTextModel
    {
        [self addSubview:self.scrollView];
        [[MagicWebViewWebPManager shareManager] registerMagicURLProtocolWebView:self.webView];
        [self.scrollView addSubview:self.webView];
        [self.scrollView addSubview:self.recommendLabel];
        [self.scrollView addSubview:self.collectionView];
        [self.webView.scrollView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:nil];
        
        MC_SELF_WEAK(self)
        MagicScrollPageRefreshHeader *header = [MagicScrollPageRefreshHeader headerWithRefreshingBlock:^{
            [weakself.scrollView.mj_header endRefreshing];
            [weakself executeProductLoadMorePicTextViewGoTop];
        }];
        self.scrollView.mj_header = header;
    }
    
    #pragma mark -Lazy
    - (UIScrollView *)scrollView
    {
        if (!_scrollView) {
            _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
            _scrollView.backgroundColor = [UIColor colorWithRed:0.95 green:0.95 blue:0.95 alpha:1.00];
        }
        return _scrollView;
    }
    
    - (UIWebView *)webView
    {
        if (!_webView) {
            _webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
            _webView.delegate = self;
            _webView.scrollView.bounces = NO;
            _webView.scrollView.showsHorizontalScrollIndicator = NO;
            _webView.scrollView.scrollEnabled = NO;
            _webView.scalesPageToFit = YES;
        }
        return _webView;
    }
    
    - (UILabel *)recommendLabel{
        if (!_recommendLabel) {
            _recommendLabel = [[UILabel alloc] init];
            _recommendLabel.text = @"   更多推荐";
            _recommendLabel.textColor = [UIColor colorWithRed:0.30 green:0.30 blue:0.30 alpha:1.00];
            _recommendLabel.font = [UIFont systemFontOfSize:12];
            _recommendLabel.backgroundColor = [UIColor whiteColor];
        }
        return _recommendLabel;
    }
    
    - (UICollectionView *)collectionView
    {
        if (!_collectionView) {
            UICollectionViewFlowLayout *flowLayout = [UICollectionViewFlowLayout new];
            flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, recommendItemSpace);
            flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
            flowLayout.itemSize = CGSizeMake(recommendItemWidth, recommendViewHeight);
            _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
            _collectionView.backgroundColor = [UIColor whiteColor];
            _collectionView.delegate = self;
            _collectionView.dataSource = self;
            [_collectionView registerClass:[ProductLoadMorePicTextCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
        }
        return _collectionView;
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"contentSize"]) {
            CGSize resize = [self.webView sizeThatFits:CGSizeZero];
            self.webView.frame =  CGRectMake(0, 0, CGRectGetWidth(self.frame), resize.height);
            self.recommendLabel.frame = CGRectMake(0, CGRectGetMaxY(self.webView.frame) + recommendViewSpace, CGRectGetWidth(self.frame), recommendTitleHeight);
            self.collectionView.frame = CGRectMake(0, CGRectGetMaxY(self.recommendLabel.frame), CGRectGetWidth(self.frame), recommendViewHeight);
            self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.frame), CGRectGetMaxY(self.collectionView.frame) + recommendViewSpace);
        }
    }
    
    -(void)dealloc
    {
        [[MagicWebViewWebPManager shareManager] unregisterMagicURLProtocolWebView:self.webView];
        [self.webView.scrollView removeObserver:self forKeyPath:@"contentSize"];
        self.scrollView = nil;
        self.webView = nil;
        self.collectionView = nil;
        self.recommendDataArray = nil;
        self.picTextDataArray = nil;
    }
    
    
    #pragma mark - UIWebViewDelegate
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
        return [self handleWebviewEventWithRequest:request];
    }
    
    - (void)webViewDidStartLoad:(UIWebView *)webView
    {
        
    }
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
        
    }
    
    - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
    {
        NSLog(@"商品详情web错误 %@", error);
    }
    
    - (BOOL)handleWebviewEventWithRequest:(NSURLRequest *)request
    {
        NSString *url = request.URL.absoluteString;
        NSRange range = [url rangeOfString:@"selectIndex="];
        if (range.location != NSNotFound) {
            NSInteger begin = range.location + range.length;
            NSString *index = [url substringFromIndex:begin];
            [self executeProductLoadMorePicTextViewZoomImageWithIndexString:index];
            return NO;
        }
        return YES;
    }
    
    #pragma mark - CustomHTML
    
    - (void)loadWebViewCustomHTMLWithImageUrls:(NSArray *)imageUrls
    {
        NSMutableString *html = [NSMutableString string];
        [html appendString:@"<html>"];
        [html appendString:@"<head>"];
        [html appendString:@"</head>"];
        [html appendString:@"<body>"];
        [html appendString:[self settingWebViewBodyWithImageUrlArray:imageUrls]];
        [html appendString:@"</body>"];
        [html appendString:@"</html>"];
        [self.webView loadHTMLString:html baseURL:nil];
    }
    
    - (NSString *)settingWebViewBodyWithImageUrlArray:(NSArray *)imageUrlArray
    {
        NSMutableString *body = [NSMutableString string];
        for (NSInteger i = 0; i < imageUrlArray.count; i++) {
            NSString *imgUrl = [NSString stringWithFormat:@"%@", [imageUrlArray objectAtIndex:i]];
            imgUrl = [self handlerImgUrlString:imgUrl];
            NSMutableString *html = [NSMutableString string];
            [html appendString:@"<div class=\"img-box\">"];
            NSString *onload = [NSString stringWithFormat:@"this.onclick = function() {window.location.href = 'selectIndex=' + %ld;}", i];
            [html appendFormat:@"<img onload=\"%@\" style=\"clear:both; display:block; margin:auto;\" width=\"100%%\" src=\"%@\">", onload, imgUrl];
            [html appendString:@"</div>"];
            [body appendString:html];
        }
        return body;
    }
    
    #pragma mark -UICollectionViewDataSource
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
        return self.recommendDataArray.count;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
        ProductLoadMorePicTextCollectionViewCell *cell = (ProductLoadMorePicTextCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
        cell.productRecommendModel = [self.recommendDataArray objectAtIndex:indexPath.row];
        return cell;
    }
    
    #pragma mark -UICollectionViewDelegate
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
       ProductRecommend *productRecommendModel = [self.recommendDataArray objectAtIndex:indexPath.row];
       [self executeProductLoadMorePicTextViewPushProductWithSkuId:productRecommendModel.ID];
    }
    
    
    #pragma mark -ProductLoadMoreViewDelegate
    - (void)executeProductLoadMorePicTextViewZoomImageWithIndexString:(NSString *)indexString
    {
        if ([self.delegate respondsToSelector:@selector(productLoadMorePicTextViewZoomImageWithIndex:)]) {
            [self.delegate productLoadMorePicTextViewZoomImageWithIndex:[indexString integerValue]];
        }
    }
    
    - (void)executeProductLoadMorePicTextViewPushProductWithSkuId:(NSInteger)skuId
    {
        if ([self.delegate respondsToSelector:@selector(productLoadMorePicTextViewPushProductWithSkuId:)]) {
            [self.delegate productLoadMorePicTextViewPushProductWithSkuId:[NSString stringWithFormat:@"%ld", skuId]];
        }
    }
    
    - (void)executeProductLoadMorePicTextViewGoTop
    {
        if ([self.delegate respondsToSelector:@selector(productLoadMorePicTextViewGoTop)]) {
            [self.delegate productLoadMorePicTextViewGoTop];
        }
    }
    
    
    #pragma mark - Reload
    - (void)reload{
        [self loadWebViewCustomHTMLWithImageUrls:self.picTextDataArray];
        [self.collectionView reloadData];
    }
    
    #pragma mark - IMGURL
    - (NSString *)handlerImgUrlString:(NSString *)imgUrlString
    {
        NSString *result = [NetworkManager httpsSchemeHandler:imgUrlString];
        // webp
        if ([result containsString:@"showjoy.com"] && ![result hasSuffix:@".webp"]) {
            result = [result stringByAppendingString:@".webp"];
        }
        return result;
    }
    @end
    

    图文混排——使用

    ProductLoadMoreViewController中,保证两个接口都请求完成后,刷新ProductLoadMorePicTextView。

    #import "ProductLoadMoreViewController.h"
    #import "MagicNetworkManager.h"
    #import "ProductLoadMorePicTextView.h"
    
    static NSString * const SJProductAPI = @"https://shopappserver.showjoy.com/api/shop/sku";
    static NSString * const SJProductPicTextAPI = @"https://shopappserver.showjoy.com/api/shop/item/pictext";
    static NSString * const SJProductSkuId = @"146931";
    
    
    @interface ProductLoadMoreViewController () <ProductLoadMorePicTextViewDelegate>
    
    @end
    
    @implementation ProductLoadMoreViewController{
        ProductDetailModel *_productModel;
        ProductLoadMorePicTextModel *_productPicTextModel;
        ProductLoadMorePicTextView *_picTextView;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.view.backgroundColor = [UIColor grayColor];
        [self networkRequestData];
    }
    
    #pragma mark - Network
    - (void)networkRequestData
    {
       [QuicklyHUD showWindowsProgressHUDText:@"加载中..."];
        dispatch_group_t group = dispatch_group_create();
        dispatch_queue_t serialQueue = dispatch_queue_create("product_group", DISPATCH_QUEUE_SERIAL);
        
        // 商品信息
        dispatch_group_enter(group);
        dispatch_group_async(group, serialQueue, ^{
            [[MagicNetworkManager shareManager] GET:SJProductAPI Parameters:@{@"skuId" : SJProductSkuId} Success:^(NSURLResponse *response, id responseObject) {
                [ProductDetailModel mj_setupObjectClassInArray:^NSDictionary *{
                    return @{@"shop" : [ProductShop class],
                             @"skuList" : [ProductSkuList class],
                             @"value" : [ProductValue class],
                             @"saleInfo" : [ProductSaleInfo class],
                             @"recommend" : [ProductRecommend class],
                             @"skuCommission" : [ProductSkuCommission class],
                             @"item" : [ProductItem class],
                             @"tagSkus" : [ProductTagSkus class],
                             @"tagMap" : [ProductTagMap class],
                             @"skuEnsures" : [ProductSkuEnsures class],
                             @"salesPromotion" : [ProductSalesPromotion class]};
                }];
                _productModel = [ProductDetailModel mj_objectWithKeyValues:[responseObject valueForKey:@"data"]];
                dispatch_group_leave(group);
            } Failure:^(NSURLResponse *response, id error) {
                dispatch_group_leave(group);
            }];
        });
        
        // 图文信息
        dispatch_group_enter(group);
        dispatch_group_async(group, serialQueue, ^{
            [[MagicNetworkManager shareManager] GET:SJProductPicTextAPI Parameters:@{@"skuId" : SJProductSkuId} Success:^(NSURLResponse *response, id responseObject) {
                [ProductLoadMorePicTextModel mj_setupObjectClassInArray:^NSDictionary *{
                    return @{@"item" : [PicTextItem class],
                             @"itemPic" : [PicTextItemPic class],
                             @"spu" : [PicTextSpu class]};
                }];
                _productPicTextModel = [ProductLoadMorePicTextModel mj_objectWithKeyValues:[responseObject valueForKey:@"data"]];
                dispatch_group_leave(group);
            } Failure:^(NSURLResponse *response, id error) {
                dispatch_group_leave(group);
            }];
        });
        
        // 主线程刷新UI
        dispatch_group_notify(group, serialQueue, ^{
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                dispatch_async(dispatch_get_main_queue(), ^{
                    [QuicklyHUD hiddenMBProgressHUDForView:MC_APP_WINDOW];
                    [self reloadPicTextView];
                });
            });
        }); 
    }
    
    #pragma mark - Reload
    - (void)reloadPicTextView
    {
        if (_picTextView) {
            [_picTextView removeFromSuperview];
            _picTextView.delegate = nil;
            _picTextView = nil;
        }
        CGFloat border = 20.0f;
        _picTextView = [[ProductLoadMorePicTextView alloc] initWithFrame:CGRectMake(border, border, MC_SCREEN_W - 2 * border, MC_SCREEN_H - MC_NAVIGATION_BAR_H - MC_STATUS_BAR_H - 2 * border) productDetailModel:_productModel picTextModel:_productPicTextModel];
        _picTextView.delegate = self;
        [self.view addSubview:_picTextView];
        [_picTextView reload];
    }
    
    #pragma mark - ProductLoadMorePicTextViewDelegate
    - (void)productLoadMorePicTextViewGoTop
    {
        [QuicklyHUD showWindowsOnlyTextHUDText:@"Go Top"];
    }
    
    - (void)productLoadMorePicTextViewZoomImageWithIndex:(NSInteger)index
    {
        [QuicklyHUD showWindowsOnlyTextHUDText:[NSString stringWithFormat:@"img: %ld", index]];
    }
    
    - (void)productLoadMorePicTextViewPushProductWithSkuId:(NSString *)skuId
    {
        [QuicklyHUD showWindowsOnlyTextHUDText:[NSString stringWithFormat:@"skuId: %@", skuId]];
    }
    @end
    

    Demo

    MagicCubeKit - 实验室 - ProductLoadMoreViewController

    相关文章

      网友评论

      本文标题:iOS中UIScrollView、UIWebView、UICol

      本文链接:https://www.haomeiwen.com/subject/pcbxixtx.html