将 SKProduct 价格提取到 UICollectionView 单元格标签中

Posted

技术标签:

【中文标题】将 SKProduct 价格提取到 UICollectionView 单元格标签中【英文标题】:Fetching SKProduct Price into UICollectionView Cell Label 【发布时间】:2020-02-19 15:12:35 【问题描述】:

我遇到了一个问题,当我将 SKProduct 区域设置价格提取到我的 UICollectionView 的 label.text 上时,它显示正确,但是价格会根据页面的加载速度在不同的标签中跳来跳去。

TopUpViewController (UICollectionView) -> TopUpMoneyCell (MoneyLabel)

知道如何解决这个问题吗?目前我在 TopUpMoneyCell 中调用 SKProduct。我有一组 4 个要调用的应用程序产品,每个都有不同的值。

我应该改为从 TopUpViewController 调用它吗?如果是这样,我应该如何将我从 TopUpViewController 获得的数据提取到 TopUpMoneyCell?

编辑 1:添加 UI Mockup,再次感谢您的评论。

View of UI Mockup

【问题讨论】:

“价格在不同标签中跳来跳去”是什么意思?你的意思是不同的集合视图单元格吗?无论如何,您必须显示相关代码。如果没有所有这些信息,我的疯狂猜测是,它可能与以下事实有关,即当在滚动期间不再可见时,通常会重新使用集合视图单元格。 谢谢。我已经更新了图像以提供更清晰的视图 【参考方案1】:

看看在您的TopUpMoneyCell 中覆盖prepareForReuse() 函数。在该函数中,取消您可能已经开始加载价格的所有异步调用。

【讨论】:

【参考方案2】:

在没有看到任何代码的情况下,很难看到您在做什么,但听起来您可能希望您的 TopUpViewController 符合 UICollectionViewDataSource 协议 (https://developer.apple.com/documentation/uikit/uicollectionviewdatasource?language=objc)

然后你可以在那里实现类似以下的东西:


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath

    UICollectionViewCell* cell = [self.testCollectionView dequeueReusableCellWithReuseIdentifier:@"SomeReuseID"
                                                                                    forIndexPath:indexPath];

    // set your custom labeling on the cell here (you probably have a subclass)

    return cell;

不要忘记告诉 UICollectionView 为它的数据源使用什么。

根据您的描述,听起来您的单元格正在直接查询某些数据源,因此当 UICollectionView 选择重用单元格时,标签不是您想要的顺序。

【讨论】:

【参考方案3】:

好的,我设法解决了我的问题。如果有人可以帮助简化我的代码将不胜感激:) 下面是代码的摘录。

#import "TopUpMoneyCell.h"
#import "TopUpMoneyModel.h"
#import <StoreKit/StoreKit.h>

@interface TopUpMoneyCell() <SKProductsRequestDelegate>
@property (nonatomic,strong) NSString *purchID;
@property (nonatomic,strong) NSArray *products;
@property (nonatomic,strong) NSArray *productID;
@property (nonnull,strong) IAPCompletionHandle handle;
@property (strong,nonatomic) SKProductsRequest *request;
@property (strong,nonatomic) SKProduct *firstProduct;
@property (strong,nonatomic) SKProduct *secondProduct;
@property (strong,nonatomic) SKProduct *thirdProduct;
@property (strong,nonatomic) SKProduct *fourthProduct;
@property (strong,nonatomic) NSString *firstProductPrice;
@property (strong,nonatomic) NSString *secondProductPrice;
@property (strong,nonatomic) NSString *thirdProductPrice;
@property (strong,nonatomic) NSString *fourthProductPrice;
@property (nonatomic, weak) UILabel *firstPriceLabel;
@property (nonatomic, weak) UILabel *secondPriceLabel;
@property (nonatomic, weak) UILabel *thirdPriceLabel;
@property (nonatomic, weak) UILabel *fourthPriceLabel;
@end

@implementation AQTopUpMoneyCell

- (UILabel *)priceLabel 
    if (!_priceLabel) 
        UILabel *label = [[UILabel alloc] init];
        _priceLabel = label;
        label.textAlignment = NSTextAlignmentCenter;
        label.text = @"";
    
    return _priceLabel;


- (instancetype)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 
        [self productsInfoRequest];
        [self cnyLabel];
    
    return self;


- (void)productsInfoRequest 
                _productID = [NSArray arrayWithObjects:@"100",@"200",@"300",@"400", nil];
               SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:_productID]];
                request.delegate = self;
                [request start];
    

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
    
        NSSortDescriptor *mySortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"price" ascending:NO];
        NSMutableArray *_productsAvailable = [[NSMutableArray alloc] initWithArray:response.products];
        [_productsAvailable sortUsingDescriptors:[NSArray arrayWithObject:mySortDescriptor]];

        self.firstProduct = response.products[0];
        self.secondProduct = response.products[1];
        self.thirdProduct = response.products[2];
        self.fourthProduct = response.products[3];

        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
        [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
        [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
        [numberFormatter setLocale:_firstProduct.priceLocale];
        self.firstProductPrice = [numberFormatter stringFromNumber:_firstProduct.price];
        self.secondProductPrice = [numberFormatter stringFromNumber:_secondProduct.price];
        self.thirdProductPrice = [numberFormatter stringFromNumber:_thirdProduct.price];
        self.fourthProductPrice = [numberFormatter stringFromNumber:_fourthProduct.price];

        static int counter = 0;
        if (counter == 4) 
            counter = 0;
        
        if ( [_productsAvailable count] > 0)
            if (_indexPath.row == 0)
            [self.priceLabel setText:_firstProductPrice];
            if (_indexPath.row == 1)
            [self.priceLabel setText:_secondProductPrice];
            if (_indexPath.row == 2)
            [self.priceLabel setText:_thirdProductPrice];
            if (_indexPath.row == 3)
            [self.priceLabel setText:_fourthProductPrice];
            counter++;
        
    

#pragma mark - SKProductsRequestDelegate
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
#if DEBUG
    NSLog(@"log-IAP> request -> failedWithError: %@", error);
    [SVProgressHUD showErrorWithStatus:@"Request timed out. Try again later."];
#endif


- (void)requestDidFinish:(SKRequest *)request
#if DEBUG
    NSLog(@"log-IAP> requestDidFinish?");
#endif



- (void)setIndexPath:(NSIndexPath *)indexPath 
    _indexPath = indexPath;
    NSString *imageName = [NSString stringWithFormat:@"touupbg_%ld",indexPath.row];
    self.bgImageV.image = [UIImage imageNamed:imageName];
    if (indexPath.row == 0) 
        [self.bgImageV mas_updateConstraints:^(MASConstraintMaker *make) 
            make.height.equalTo(kScale(367*scale));
            make.width.equalTo(kScale(308*scale));
        ];
     else if (indexPath.row == 1) 
        [self.bgImageV mas_updateConstraints:^(MASConstraintMaker *make) 
            make.height.equalTo(kScale(380*scale));
            make.width.equalTo(kScale(308*scale));
        ];
    else if (indexPath.row == 2) 
        [self.bgImageV mas_updateConstraints:^(MASConstraintMaker *make) 
            make.height.equalTo(kScale(373*scale));
            make.width.equalTo(kScale(316*scale));
        ];
    else if (indexPath.row == 3) 
        [self.bgImageV mas_updateConstraints:^(MASConstraintMaker *make) 
            make.height.equalTo(kScale(403*scale));
            make.width.equalTo(kScale(308*scale));
        ];
    else if (indexPath.row == 4) 
        [self.bgImageV mas_updateConstraints:^(MASConstraintMaker *make) 
            make.height.equalTo(kScale(400*scale));
            make.width.equalTo(kScale(308*scale));
        ];
    else if (indexPath.row == 5) 
        [self.bgImageV mas_updateConstraints:^(MASConstraintMaker *make) 
            make.height.equalTo(kScale(401*scale));
            make.width.equalTo(kScale(317*scale));
        ];
    

@end

【讨论】:

以上是关于将 SKProduct 价格提取到 UICollectionView 单元格标签中的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SKProduct 价格格式化为 Swift 货币字符串?

获取以美元为单位的 SKProduct 价格,而不是商店区域设置价格

iOS SKProduct 如何获取IAP的免费试用信息?

自动续订订阅 SKProduct.PeriodUnit == 7

SKProduct Swift - 信息从何而来?

SKProduct 中的本地化标题为零