将 SKProduct 价格提取到 UICollectionView 单元格标签中
Fetching SKProduct Price into UICollectionView Cell Label
我遇到一个问题,当我将 SKProduct 区域设置价格获取到我的 UICollectionView 的 label.text 时,它显示正确,但是价格在不同的标签中跳来跳去,具体取决于如何正在快速加载页面。
TopUpViewController (UICollectionView) -> TopUpMoneyCell (MoneyLabel)
知道如何解决这个问题吗?目前我在 TopUpMoneyCell 中调用 SKProduct。我有一组 4 个应用产品要调用,每个都有不同的值。
我应该从 TopUpViewController 调用它吗?如果是这样,我应该如何将从 TopUpViewController 获取的数据提取到 TopUpMoneyCell?
编辑 1:添加了 UI 模型,再次感谢您的评论。
View of UI Mockup
看看在 TopUpMoneyCell
中重写 prepareForReuse()
函数。在该函数中,取消您可能已开始加载价格的任何异步调用。
没有看到任何代码,很难看出你在做什么,但听起来你可能想让你的 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 选择重用单元格时,标签不是您想要的顺序。
好的,我设法解决了我的问题。如果有人可以帮助简化我的代码,我将不胜感激:) 下面是代码的摘录。
#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 的 label.text 时,它显示正确,但是价格在不同的标签中跳来跳去,具体取决于如何正在快速加载页面。
TopUpViewController (UICollectionView) -> TopUpMoneyCell (MoneyLabel)
知道如何解决这个问题吗?目前我在 TopUpMoneyCell 中调用 SKProduct。我有一组 4 个应用产品要调用,每个都有不同的值。
我应该从 TopUpViewController 调用它吗?如果是这样,我应该如何将从 TopUpViewController 获取的数据提取到 TopUpMoneyCell?
编辑 1:添加了 UI 模型,再次感谢您的评论。
View of UI Mockup
看看在 TopUpMoneyCell
中重写 prepareForReuse()
函数。在该函数中,取消您可能已开始加载价格的任何异步调用。
没有看到任何代码,很难看出你在做什么,但听起来你可能想让你的 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 选择重用单元格时,标签不是您想要的顺序。
好的,我设法解决了我的问题。如果有人可以帮助简化我的代码,我将不胜感激:) 下面是代码的摘录。
#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