UIImage and UILabel disappearing after doing UIRefreshControl - swift

UIImages and UILabel are disappearing in some collectionViews after refreshing inside my app.
here is my code. You can see what is wrong in the picture, the left image is before refreshing and there is a discount price label and after refreshing the simulator, it is gone. getProductLatestData(), getBestSellingData() are the Alamofire get request for API.
//For Refresh Controller
//----------------------
var player : AVAudioPlayer
var refreshController : UIRefreshControl = {
let refreshController = UIRefreshControl()
refreshController.addTarget(self, action: #selector(updateData), for: .valueChanged)
return refreshController
}()
//----------------------
//For Update Data when scroll to top
//----------------------------------
#objc func updateData(){
//To play sound when scroll top
//-----------------------------
let pathToSound = Bundle.main.path(forResource: "Flick", ofType: "wav")
let url = URL(fileURLWithPath: pathToSound!)
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch let error {
print(error.localizedDescription)
}
//-----------------------------
//Fetch Latest Products Data
getProductLatestData(pageNumber: 0, pageSize: 0)
//Fetch BestSelling Products Data
getBestSellingData(pageNumber: 0, pageSize: 0)
//Fetch Promotion Products Data
getPromotionProductsData(pageNumber: 0, pageSize: 0)
//Fetch Products By Category
getProductsByCat(pageNumber: 0, pageSize: 0)
//Fetch Reward Products
getRewardProducts()
self.refreshController.endRefreshing()
}
if collectionView == latestItemCV {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "latestItemCell", for: indexPath) as! PromotionItemsCollectionViewCell
if let percent = latestItemData[indexPath.row].promotePercent {
if percent != 0 {
cell.percentOff.isHidden = false
cell.percentOff.text = " \(percent) % Off "
cell.percentOffBackground.isHidden = false
}
else{
cell.percentOff.isHidden = true
cell.percentOffBackground.isHidden = true
}
}
if let name = latestItemData[indexPath.row].name {
cell.itemsName.text = name
}
else{
cell.itemsName.text = "-"
}
if let url = latestItemData[indexPath.row].url {
cell.itemsImageView.sd_setImage(with: URL(string: url), placeholderImage: UIImage(named: "placeholder"))
}
//----------------------------------

Thanks to #larme I recheck the code here is how I fixed it, I added those disappeared labels isHidden = false also as I did isHidden = true for them.
if let promotionPrice = latestItemData[indexPath.row].promotePrice {
if promotionPrice != 0 {
cell.originalItemsPrice.text = "\(setCommaForPrice(price: Int(promotionPrice))) Ks"
cell.promotionPercent.isHidden = false
cell.promotionLine.isHidden = false
}
else{
if let orPrice = latestItemData[indexPath.row].originalPrice {
cell.originalItemsPrice.text = "\(setCommaForPrice(price: Int(orPrice))) Ks"
}
cell.promotionPercent.isHidden = true
cell.promotionLine.isHidden = true
}
}

Related

AdMob Native ad loading but not showing

I'm using Google AdMob to display native ads on my app. I made everything as in the Google Documentation. After testing, I figured out that test ad values are loading successfully since they aren't nil and when I print them, I can see them as they should display. However data is not displaying on my GADNativeAdView. Here is some of my code:
var nativeAdView: GADNativeAdView! {
didSet {
nativeAdView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(nativeAdView)
nativeAdView.leftAnchor.constraint(equalTo: collectionView4.leftAnchor).isActive = true
nativeAdView.rightAnchor.constraint(equalTo: collectionView4.rightAnchor).isActive = true
nativeAdView.topAnchor.constraint(equalTo: collectionView4.bottomAnchor, constant: 10).isActive = true
nativeAdView.heightAnchor.constraint(equalToConstant: 310).isActive = true
}
}
var adLoader: GADAdLoader!
// MARK: - Google Mobile Ads
extension HomeController: GADNativeAdLoaderDelegate, GADNativeAdDelegate {
private func setupAd() {
let multipleAdsOptions = GADMultipleAdsAdLoaderOptions()
multipleAdsOptions.numberOfAds = 1
adLoader = GADAdLoader(adUnitID: testNativeId, rootViewController: self,
adTypes: [.native],
options: [multipleAdsOptions])
adLoader.delegate = self
adLoader.load(GADRequest())
}
func imageOfStars(from starRating: NSDecimalNumber?) -> UIImage? {
guard let rating = starRating?.doubleValue else {
return nil
}
if rating >= 5 {
return UIImage(named: "stars_5")
} else if rating >= 4.5 {
return UIImage(named: "stars_4_5")
} else if rating >= 4 {
return UIImage(named: "stars_4")
} else if rating >= 3.5 {
return UIImage(named: "stars_3_5")
} else {
return nil
}
}
func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
// Create and place ad in view hierarchy.
let nibView = Bundle.main.loadNibNamed("NativeAdView", owner: nil, options: nil)?.first
guard let nativeAdView = nibView as? GADNativeAdView else {
return
}
self.nativeAdView = nativeAdView
nativeAd.delegate = self
(nativeAdView.headlineView as? UILabel)?.text = nativeAd.headline
nativeAdView.mediaView?.mediaContent = nativeAd.mediaContent
(nativeAdView.bodyView as? UILabel)?.text = nativeAd.body
nativeAdView.bodyView?.isHidden = nativeAd.body == nil
(nativeAdView.callToActionView as? UIButton)?.setTitle(nativeAd.callToAction, for: .normal)
nativeAdView.callToActionView?.isHidden = nativeAd.callToAction == nil
(nativeAdView.iconView as? UIImageView)?.image = nativeAd.icon?.image
nativeAdView.iconView?.isHidden = nativeAd.icon == nil
(nativeAdView.starRatingView as? UIImageView)?.image = imageOfStars(from: nativeAd.starRating)
nativeAdView.starRatingView?.isHidden = nativeAd.starRating == nil
(nativeAdView.storeView as? UILabel)?.text = nativeAd.store
nativeAdView.storeView?.isHidden = nativeAd.store == nil
(nativeAdView.priceView as? UILabel)?.text = nativeAd.price
nativeAdView.priceView?.isHidden = nativeAd.price == nil
(nativeAdView.advertiserView as? UILabel)?.text = nativeAd.advertiser
nativeAdView.advertiserView?.isHidden = nativeAd.advertiser == nil
nativeAdView.callToActionView?.isUserInteractionEnabled = false
nativeAdView.nativeAd = nativeAd
}
func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: Error) {
print("ERROR: \(error.localizedDescription)")
}
}
Here is my .xib file:
The views custom class on the .xib file are set.
After trial and error I figured out that using #IBOutlet for views in the .xib file and calling them on the adLoader(_:) worked.

How to randomize cards data from model array without repetition

I am displaying cards data from my model array, how do i randomize card data everytime i start the app and should not be repetitive. I am using ZLSwipeable view library for creating cards fro swipe feature. this is the function in which i have write all my code for swipe cards, and in the code wordsdata is the model array that i have declaredlike this var wordsdata = ModelRsult.
CardView is the view i am displaying my cards into
screenshot of my card display screen
in the image it is shown banana as the first data, now when i run the app again it should show me another data first and so on
my source code:
func nextCardView() -> UIView?
{
let arrayData = wordsData
if (self.colorIndex >= arrayData.count)
{
return nil
}
let cardView = CardView(frame: swipeableView.bounds)
if loadCardsFromXib
{
let contentView = Bundle.main.loadNibNamed("CardContentView", owner: self, options: nil)?.first! as! CardView
contentView.superVC = self
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = cardView.backgroundColor
cardView.addSubview(contentView)
let data = arrayData[(self.colorIndex)] as ModelResult
contentView.wordModel = data
let savedValue = UserDefaults.standard.bool(forKey: "isLangChanged")
tempLangChanged = savedValue
if tempLangChanged == false
{
if let spanishName = data.cardWordEnglish, spanishName.count != 0
{
contentView.wordSpanish.text = spanishName
print(spanishName)
}
}
else
{
if let dict = data.cardWordImage, dict.count != 0
{
let url = WS_wordIconUrl + dict
contentView.wordImage.kf.indicatorType = .activity
contentView.wordImage.kf.setImage(with: URL(string: url))
}
if let spanishName = data.cardWordSpanish, spanishName.count != 0
{
contentView.wordSpanish.text = spanishName
print(spanishName)
}
}
contentView.soundBtn.addTarget(self, action:#selector(self.soundBtn(sender:)), for: .touchUpInside)
contentView.hideCard.addTarget(self, action:#selector(self.hideCard(sender:)), for: .touchUpInside)
contentView.soundBtn.tag = self.colorIndex
contentView.hideCard.tag = self.colorIndex
cardView.tag = self.colorIndex
constrain(contentView, cardView) { view1, view2 in
view1.left == view2.left
view1.top == view2.top
view1.width == cardView.bounds.width
view1.height == cardView.bounds.height
}
}
colorIndex += 1
return cardView
}
The best way for this problem is to shuffle the array where your cards are and then use it. In your case, I would shuffle it at the app start.
array.shuffle()

Loading UIImage in CollectionView Cell movement freezes

I have a UICollectionViewCell with 1 to 3 UIImageView that are managed by a stackView.
The Images all have around 8mb. I load them async from CoreData before calling collectionView.reload()
In this setup the collection view freezes when moving while loading new cells.
I tried it with smaller Images and then it did not freeze.
I now scale the Images down before loading them in to the UIImageView. But it leads to other weird behaviour like first showing the picture from the other cell and then adding the correct ones.
override func configureCellAtIndexPath(item: Journaling) {
super.configureCellAtIndexPath(item: item)
let imageOne = UIImageView()
let imageTwo = UIImageView()
let imageThree = UIImageView()
imageContainer = nil
imageOne.image = nil
imageTwo.image = nil
imageThree.image = nil
if item.image.count == 1 {
let group = DispatchGroup()
group.enter()
var downsizedImage = [UIImage]()
DispatchQueue.global().async {
downsizedImage.append(item.image[0].downsizeImage(.low)!)
group.leave()
}
group.notify(queue: .main) {
imageOne.image = downsizedImage[0]
imageTwo.image = nil
imageThree.image = nil
self.setUpStackView([imageOne])
}
}
if item.image.count == 2 {
let group = DispatchGroup()
group.enter()
var downsizedImage = [UIImage]()
DispatchQueue.global().async {
downsizedImage.append(item.image[0].downsizeImage(.low)!)
downsizedImage.append(item.image[1].downsizeImage(.low)!)
group.leave()
}
group.notify(queue: .main) {
imageOne.image = downsizedImage[0]
imageTwo.image = downsizedImage[1]
imageThree.image = nil
self.setUpStackView([imageOne,imageTwo])
}
}
if item.image.count > 2 {
let group = DispatchGroup()
group.enter()
var downsizedImage = [UIImage]()
DispatchQueue.global().async {
downsizedImage.append(item.image[0].downsizeImage(.low)!)
downsizedImage.append(item.image[1].downsizeImage(.low)!)
downsizedImage.append(item.image[2].downsizeImage(.low)!)
group.leave()
}
group.notify(queue: .main) {
imageOne.image = downsizedImage[0]
imageTwo.image = downsizedImage[1]
imageThree.image = downsizedImage[2]
self.setUpStackView([imageOne,imageTwo,imageThree])
}
}
imageOne.contentMode = .scaleAspectFill
imageOne.clipsToBounds = true
imageTwo.contentMode = .scaleAspectFill
imageTwo.clipsToBounds = true
imageThree.contentMode = .scaleAspectFill
imageThree.clipsToBounds = true
}
func setUpStackView(_ views: [UIView]) {
self.imageContainer = UIStackView(arrangedSubviews: views)
self.imageContainer.axis = .horizontal
self.imageContainer.distribution = .fillEqually
placeholder.sv(imageContainer)
imageContainer.addConstrainsToSuperView(distance: 0, superView: placeholder)
}

YPImagePicker and sending image and video to another controller

I am trying to send a photo and video from one controller to another with the YPImagePicker pod. I am having an issue understanding how to use this file.
var selectedItems = [YPMediaItem]()
let selectedImageV = UIImageView()
#objc func showPicker() {
var config = YPImagePickerConfiguration()
config.library.mediaType = .photoAndVideo
config.library.onlySquare = true
config.showsFilters = false
config.shouldSaveNewPicturesToAlbum = true
config.albumName = "RecipeSharing"
config.video.compression = AVAssetExportPresetMediumQuality
config.startOnScreen = .library
config.screens = [.library, .photo, .video]
config.video.recordingTimeLimit = 5.0
config.video.libraryTimeLimit = 500.0
config.video.trimmerMaxDuration = 60.0
config.video.trimmerMinDuration = 3.0
config.video.fileType = .mov
config.showsCrop = .rectangle(ratio: (16/9))
config.targetImageSize = YPImageSize.original
config.wordings.libraryTitle = "Gallery"
config.hidesStatusBar = false
config.hidesBottomBar = false
config.library.maxNumberOfItems = 5
let picker = YPImagePicker(configuration: config)
picker.didFinishPicking { [unowned picker] items, _ in
if let photo = items.singlePhoto {
let finalShareVC = NewInstructionsController()
picker.navigationController?.pushViewController(finalShareVC, animated: true)
}
}
picker.didFinishPicking { [unowned picker] items, _ in
if let video = items.singleVideo {
let finalShareVC = NewInstructionsController()
picker.navigationController?.pushViewController(finalShareVC, animated: true)
}
}
present(picker, animated: true, completion: nil)
}
My Second Controller has the the code as the following.
var selectedImage: UIImage? {
didSet {
guard let image = selectedImage else { return }
instructionsImage.image = image
}
}
This is used to receive the file the photo I believe. Does anyone know what I have to use to send a photo and video to another controller so that it can be used. I have tried reading a lot on this pod. I get to the save option in this pod and then it does not do anything. I was wondering if anyone had an idea or could help me. Maybe I dont need to push the view but I am unsure. Thank you.

How to show edit button on uitableviewcell, only on the posts you posted yourself

I'm making an app with a login feature, in which you can post, edit, and delete your own favorite spots, and like the posts of other users.
I'm trying to implement an edit button, that only shows on the posts you posted yourself, and hidden on the posts from others.
I have my FeedViewController, in which I call the 'configureCell function' in the UITableviewCell class. This is a part of the code in the FeedViewController:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCellWithIdentifier("PostCell") as? PostCell {
let postList = searchController.active ? searchResult[indexPath.row] : posts[indexPath.row]
let post = postList
cell.request?.cancel()
var image: UIImage?
if let url = post.postImgUrl {
image = FeedVC.imageCache.objectForKey(url) as? UIImage
}
var image2: UIImage?
if let url2 = post.userImgUrl {
image2 = FeedVC.imageCache.objectForKey(url2) as? UIImage
}
cell.configureCell(post, img: image, img2: image2)
return cell
} else {
return PostCell()
}
}
This is the code in my UITableviewCell (class PostCell: UITableViewCell):
func configureCell(post: Post, img: UIImage?, img2: UIImage?) {
self.post = post
likeRef = DataService.ds.REF_USER_CURRENT.childByAppendingPath("likes").childByAppendingPath(post.postKey)
self.descriptionText.text = post.postDescription
self.descriptionText.scrollRangeToVisible(NSMakeRange(0, 0))
self.likesLbl.text = "\(post.likes)"
self.postTitle.text = post.postTitle
self.postLocation.text = post.postLocation
self.username.text = post.username
self.postKeyLbl.text = post.key
if post.postImgUrl != nil {
if img != nil {
self.showcaseImg.image = img
} else {
request = Alamofire.request(.GET, post.postImgUrl!).validate(contentType: ["image/*"]).response(completionHandler: { request, response, data, err in
if err == nil {
let _img = UIImage(data: data!)!
self.showcaseImg.image = img
FeedVC.imageCache.setObject(_img, forKey: self.post.postImgUrl!)
} else {
print(err.debugDescription)
}
})
}
} else {
self.showcaseImg.hidden = true
}
if post.userImgUrl != nil {
if img2 != nil {
self.profileImg.image = img2
} else {
request = Alamofire.request(.GET, post.userImgUrl!).validate(contentType: ["image/*"]).response(completionHandler: { request, response, data, err in
if err == nil {
let _img2 = UIImage(data: data!)!
self.profileImg.image = img2
FeedVC.imageCache.setObject(_img2, forKey: self.post.userImgUrl!)
} else {
print(err.debugDescription)
}
})
}
} else {
print("no image")
}
likeRef.observeSingleEventOfType(.Value, withBlock: { snapshot in
if snapshot.value is NSNull {
self.likesImg.image = UIImage(named: "heart")
} else {
self.likesImg.image = UIImage(named: "heart-filled")
}
})
let getUid = NSUserDefaults.standardUserDefaults().valueForKey(KEY_UID)
if String(getUid!) == (self.post.postUid) {
editBtn.hidden = false
delBtn.hidden = false
}
}
It's about the last part:
let getUid = NSUserDefaults.standardUserDefaults().valueForKey(KEY_UID)
if String(getUid!) == (self.post.postUid) {
editBtn.hidden = false
delBtn.hidden = false
}
That part isn't working. The edit (and delete) button are showing in the posts of the specific user, but also in some of the posts of other users. I don't know what I'm doing wrong. Maybe it's because I have also implemented a 'sorting data function', where I am sorting the posts on 'date' or 'likes'. When the posts reshuffle, more edit buttons appear on random cells (from other users).
But I really don't know. I hope someone is able to help me!? Let me know if you need some more code:-) Thanks a lot!
Kind regards,
Dide
Add an else clause to this:
if String(getUid!) == (self.post.postUid) {
editBtn.hidden = false
delBtn.hidden = false
} else {
editBtn.hidden = true
delBtn.hidden = true
}
Because you are reusing cells, some of the cells where the buttons may not be hidden because it is associated with a post of a certain user may be reused for another post of a different user. Since you don't have an else clause handling this situation, those buttons whose 'hidden' property were originally set to false will remain unhidden, even if the postUid and getUid do not match. Hope this helps!