iOS: Set setImageInputs of image slideshow to array of images - ios

I'm using an image slideshow from here:
iconArr = [UIImage(named: "home-min")!,UIImage(named: "category-
min")!,UIImage(named: "settings-min")!,UIImage(named: "contact us-min")!,UIImage(named: "about us-min")!,UIImage(named: "logout")!]
I need to make this array as an image source.
for image in self.iconArr {
let img = image
self.SlideShow.setImageInputs([ImageSource(image: img)])
}
But that is not working, how can I do that?

you should try this way for sure, because you reset inputs in your for-loop
var imageSource: [ImageSource] = []
for image in self.iconArr {
let img = image
imageSource.append(ImageSource(image: img))
}
self.SlideShow.setImageInputs(imageSource)
As sooper stated, can be done this way
let imageSources = self.iconArr.map { ImageSource(image: $0) }

I found a solution from this url [https://stackoverflow.com/a/50461970/5628693][1]
Below is my code working fine :
var imageSDWebImageSrc = [SDWebImageSource]()
#IBOutlet weak var slideshow: ImageSlideshow!
Add below viewDidLoad()
slideshow.backgroundColor = UIColor.white
slideshow.slideshowInterval = 5.0
slideshow.pageControlPosition = PageControlPosition.underScrollView
slideshow.pageControl.currentPageIndicatorTintColor = UIColor.lightGray
slideshow.pageControl.pageIndicatorTintColor = UIColor.black
slideshow.contentScaleMode = UIViewContentMode.scaleAspectFill
// optional way to show activity indicator during image load (skipping the line will show no activity indicator)
slideshow.activityIndicator = DefaultActivityIndicator()
slideshow.currentPageChanged = {
page in
print("current page:", page)
}
let recognizer = UITapGestureRecognizer(target: self, action: #selector(Dashboard.didTap))
slideshow.addGestureRecognizer(recognizer)
} // now add below func
#objc func didTap() {
let fullScreenController = slideshow.presentFullScreenController(from: self)
// set the activity indicator for full screen controller (skipping the line will show no activity indicator)
fullScreenController.slideshow.activityIndicator = DefaultActivityIndicator(style: .white, color: nil)
}
And last step i was getting json data from below alamofire request
Alamofire.request(url, method: .post, parameters: data, encoding: JSONEncoding.default).responseJSON { response in
if(response.value == nil){
}
else {
let json2 = JSON(response.value!)
switch response.result {
case .success:
self.indicator.stopAnimating()
if let details = json2["imgs"].array {
for dItem in details {
let img = dItem["img"].stringValue
let image = SDWebImageSource(urlString: self.imgurl+img)
self.imageSDWebImageSrc.append(image!)
}
self.slideshow.setImageInputs(self.imageSDWebImageSrc)
}
break
case .failure( _):
break
}
}
}
Thanks dude :) happy coding

Related

How to delete cached SDWebImage from a button's imageView

So I have a UIButton whose imageView is set to an image using a download URL. For this purpose I use SDWebImage.
Problem is, when I press the delete button, I want the image to completely disappear but I guess it does not work because the image is still being retrieved from cache. How do I solve this?
class ViewController: UIViewController{
var profileButton: UIButton = {
let button = UIButton(type: .system)
return button
}()
var user: User?
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(profileButton)
profileButton.addTarget(self, action: #selector(handleDelete), for: .touchUpInside)
self.loadUserPhotos()
}
fileprivate func loadUserPhotos(){
let profileImageUrl = self.user?.profileImageUrl1
if let imageUrl = profileImageUrl, let url = URL(string: imageUrl){
SDWebImageManager.shared().loadImage(with: url, options: .continueInBackground, progress: nil) { (image, _, _, _, _, _) in
self.profileButton.setImage(image?.withRenderingMode(.alwaysOriginal), for: .normal)
}
}
}
#objc func handleDelete(){
self.user?.profileImageUrl1 = ""
self.profileButton.imageView?.image = nil
self.loadUserPhotos()
}
}
To remove the image from UIButton you need to mention the state as well.
self.profileButton.setImage(nil, for: .normal)
You can use :
SDImageCache.shared.removeImage(forKey: url?.description, withCompletion: nil)

How to append an optional UIImage to an array

I have a UIViewController with 2 UITextFields and 1 UIImageView (the image is optional)
When I click Save I want to save all values in an array of objects. But the image (selectedImage) is not mandatory.
The issue is with the UIImage because is asking me for an optional value for the UIImage if I don't have an image. And I don't know what to assign because I don't want to have any image in my array if the user did't picked a picture. And I've tried to put a NIL value but is not working.
Here is my code for Model:
import Foundation
import UIKit
class RoadsideDefect {
var vehicleReg: String
var detailsDefect: String
var imagesDefect: [UIImage]?
init(vehicleRegistration: String, detailsOfDefect: String, imagesOfDefects: [UIImage]?) {
self.vehicleReg = vehicleRegistration
self.detailsDefect = detailsOfDefect
self.imagesDefect = imagesOfDefects
}
}
Here is the code in the Controller:
var vehicleReg = ""
var detailsDefect = ""
var imagesDefect: [UIImage]? = [UIImage]()
var roadsideDefect: [RoadsideDefect] = []
//MARK: Save button tapped
#IBAction func saveBtnTapped(_ sender: UIBarButtonItem) {
guard let vehicleRegText = vehicleRegTextfieldOutlet.text, !vehicleRegText.isBlank else {
showAlertWithTitle(title: "Error", message: "Please add vehicle reg number.")
return
}
guard let detailsText = detailsTextfieldOutlet.text, !detailsText.isBlank else {
showAlertWithTitle(title: "Error", message: "Please add some details.")
return
}
let selectedImage: UIImage? = roadsideDefectImageView?.image
vehicleReg = vehicleRegText
detailsDefect = detailsText
// ISSUE HERE
UIImageWriteToSavedPhotosAlbum(selectedImage ?? HowToSetItNilOrEmpty?, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)
roadsideDefect.append(RoadsideDefect(vehicleRegistration: vehicleReg, detailsOfDefect: detailsDefect, imagesOfDefects: imagesDefect))
print(roadsideDefect)
}
I marked the issue with a comment.
if let image = selectedImage {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)
}
You can use optional binding for unwrapping optionals.
guard let imageView = roadsideDefectImageView else { return }
guard let image = imageView.image else { return }
UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.image(_:didFinishSavingWithError:contextInfo:)), nil)

UISegment stays at same row when tableview get scrolled

I have this problem, I have a tableview with 3 different kind of news manage by segmented control. When I scrolled the news stays for example in the fifth new, if I click in the second segment, appears in the position 5 . Is not showing the news from the segment 1(the new one),at row 0 (beginning) , stays in the position I leave when I was scrolling. Why is happening this? what I'm doing wrong?. I'm using one tableview for the 3 different kinds of news and reload the tableview data every time I change the segment.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
NSLog("selectedSegmentIndex: \(self.sectionSegmentedControl.selectedSegmentIndex) - Row: \(indexPath.row)")
let cell:UITableViewCell = self.tableview.dequeueReusableCellWithIdentifier("Cell")!
// Grab the elements using the tag
let labelTitle:UILabel? = cell.viewWithTag(1) as! UILabel?
let labelSection:UILabel? = cell.viewWithTag(2) as! UILabel?
let labelDate:UILabel? = cell.viewWithTag(3) as! UILabel?
let imageView:UIImageView? = cell.viewWithTag(4) as! UIImageView?
// Check which segment to get data from
switch self.sectionSegmentedControl.selectedSegmentIndex {
case 0:
// If segment is 0, take data from cover News
if (indexPath.row <= self.coverNews.count - 1){
//Current new to display
let currentNewToDisplay = self.coverNews[indexPath.row]
//let currentNewToDisplay = self.news[indexPath.row]
// Get the image and assign to the imageView
if let actualImageView = imageView {
// Imageview actually exists
if currentNewToDisplay.imageUrl != "" {
// Image url exists, so download it
let imageUrl:NSURL? = NSURL(string: currentNewToDisplay.imageUrl)
// Download image with SDWebImage library
if let url = imageUrl {
actualImageView.sd_setImageWithURL(url)
}
}
}
// Get the news title and assign to the label
if let actualLabelTitle = labelTitle {
let title = currentNewToDisplay.title
actualLabelTitle.text = title
actualLabelTitle.numberOfLines = 0
actualLabelTitle.minimumScaleFactor = 0.1
}
// Get the news date and assign to the label
if let actualLabelDate = labelDate {
let character = "| "
actualLabelDate.text = character + currentNewToDisplay.date_short
}
// Get the news section and assign to the label
if let actualabelSection = labelSection {
actualabelSection.text = currentNewToDisplay.section
}
}
case 1:
// If segment is 1, take data from toprated News
if (indexPath.row <= self.topratedNews.count - 1){
let currentNewToDisplay2 = self.topratedNews[indexPath.row]
// Get the image and assign to the imageView
if let actualImageView2 = imageView {
// Imageview actually exists
if currentNewToDisplay2.imageUrl != "" {
// Image url exists, so download it
let imageUrl2:NSURL? = NSURL(string: currentNewToDisplay2.imageUrl)
// Download image with SDWebImage library
if let url2 = imageUrl2 {
actualImageView2.sd_setImageWithURL(url2)
}
}
}
// Get the news title and assign to the label
if let actualLabelTitle2 = labelTitle {
actualLabelTitle2.text = currentNewToDisplay2.title
actualLabelTitle2.numberOfLines = 0
actualLabelTitle2.minimumScaleFactor = 0.1
}
// Get the news date and assign to the label
if let actualLabelDate2 = labelDate {
let character2 = "| "
actualLabelDate2.text = character2 + currentNewToDisplay2.date_short
}
// Get the news section and assign to the label
if let actualabelSection2 = labelSection {
actualabelSection2.text = currentNewToDisplay2.section
}
}
case 2:
if (indexPath.row <= self.latestNews.count - 1){
// If segment is 2, take data from latestNews News
let currentNewToDisplay3 = self.latestNews[indexPath.row]
// Get the image and assign to the imageView
if let actualImageView3 = imageView {
// Imageview actually exists
if currentNewToDisplay3.imageUrl != "" {
// Image url exists, so download it
let imageUrl3:NSURL? = NSURL(string: currentNewToDisplay3.imageUrl)
// Download image with SDWebImage library
if let url3 = imageUrl3 {
actualImageView3.sd_setImageWithURL(url3)
}
}
}
// Get the news title and assign to the label
if let actualLabelTitle3 = labelTitle {
actualLabelTitle3.text = currentNewToDisplay3.title
actualLabelTitle3.numberOfLines = 0
actualLabelTitle3.minimumScaleFactor = 0.1
}
// Get the news date and assign to the label
if let actualLabelDate3 = labelDate {
let character3 = "| "
actualLabelDate3.text = character3 + currentNewToDisplay3.date_short
}
// Get the news section and assign to the label
if let actualabelSection3 = labelSection {
actualabelSection3.text = currentNewToDisplay3.section
}
}
default:
break
}
// Set insets to zero
cell.layoutMargins = UIEdgeInsetsZero
return cell
}
// MARK: Segmented Control
#IBAction func segmentedChanged(sender: UISegmentedControl) {
switch self.sectionSegmentedControl.selectedSegmentIndex {
case 0:
// If segment is 0, return rows for coverNews array
if (self.coverNews.count == 0) {
loadNews()
}else{
dispatch_async(dispatch_get_main_queue(), {
self.tableview.reloadData()
})
}
case 1:
// If segment is 1, return rows for topratedNews array
if (self.topratedNews.count == 0) {
loadNews()
}else{
dispatch_async(dispatch_get_main_queue(), {
self.tableview.reloadData()
})
}
case 2:
// If segment is 2, return rows for latestNews array
if (self.latestNews.count == 0) {
loadNews()
}else{
dispatch_async(dispatch_get_main_queue(), {
self.tableview.reloadData()
})
}
default:
break
}
}
// MARK: Load News
func loadNews(){
switch(sectionSegmentedControl.selectedSegmentIndex){
case 0:
self.model.getFeedNews("cover")
case 1:
self.model.getFeedNews("toprated")
case 2:
self.model.getFeedNews("latest")
default:
break
}
}

textLabel.text in UIViewController comes up nil while assigning string from NSObject

I'm an iOS and programming noob so I apologize for any bad phrasing or mistakes.
I'm parsing quotes from an API for my app which displays it on a textLabel each time a UIButton is clicked. In order to keep the string from going off the textLabel or be resized to an unreadable font, I'm trying to request a new quote if the string character count is too high by calling a function in my NSObject. I set up a NSObject to do the refetching but whenever I try to reassign the the string to the textLabel.text from the NSObject or try to send the string back to the ViewController the qouteLabel.text comes back nil
Here is my viewcontroller where I'm making the initial request for the quote
import UIKit
import Alamofire
class RSQuotesViewController: RSViewController {
var ronImageView: UIImageView!
var quoteLabel = UILabel!()
override func loadView() {
let frame = UIScreen.mainScreen().bounds
let view = UIView(frame: frame)
view.backgroundColor = UIColor.grayColor()
ronImageView = UIImageView(frame: CGRectMake(frame.width/2-160, frame.height-600, 320, 600))
let ron = "ron.png"
let ronImage = UIImage(named: ron)
ronImageView.image = ronImage
view.addSubview(ronImageView);
let labelWidth = ronImageView.frame.width/2
let quoteLabelX = labelWidth-40
quoteLabel = UILabel(frame: CGRect(x: quoteLabelX, y: ronImageView.frame.height/4+15, width: labelWidth, height: 160))
quoteLabel.textAlignment = .Center
quoteLabel.text = "Click to Start"
quoteLabel.shadowColor = UIColor.grayColor()
quoteLabel.adjustsFontSizeToFitWidth = true
quoteLabel.lineBreakMode = .ByWordWrapping // or NSLineBreakMode.ByWordWrapping
quoteLabel.numberOfLines = 0
view.addSubview(quoteLabel)
self.view = view
}
override func viewDidLoad() {
super.viewDidLoad()
let frame = UIScreen.mainScreen().bounds
let getQuote = UIButton(frame: CGRect(x: 0, y: 0, width: frame.size.width+50, height: frame.size.height))
getQuote.backgroundColor = UIColor.clearColor()
getQuote.setTitle("", forState: UIControlState.Normal)
getQuote.addTarget(self, action: #selector(RSQuotesViewController.getQuote(_:)), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(getQuote)
}
// Gets quote when button is pressed
func getQuote(sender: UIButton){
let url = "http://ron-swanson-quotes.herokuapp.com/v2/quotes"
Alamofire.request(.GET, url, parameters: nil).responseJSON { response in
if let JSON = response.result.value as? Array<String>{
let quoteDict = RSQoute()
// if quote is too large get another one
if (JSON[0].characters.count > 120){
print("greater than 120")
quoteDict.fetchQuote()
} else {
self.quoteLabel.text = JSON[0]
}
}
}
}
This is my model where I'm trying to reassign the quoteLabel.text and getting nil
import UIKit
import Alamofire
class RSQoute: NSObject {
var newQuote = String()
// fetchs new quote if quote is too large
func fetchQuote(){
let url = "http://ron-swanson-quotes.herokuapp.com/v2/quotes"
Alamofire.request(.GET, url, parameters: nil).responseJSON { response in
if let JSON = response.result.value as? Array<String>{
self.newQuote = JSON[0]
if (self.newQuote.characters.count > 120) {
print("Try Again: ---->\(self.newQuote)")
return self.fetchQuote()
} else {
let quoteVC = RSQuotesViewController()
print("Retry was less than 120: ---->\(self.newQuote)")
print("quoteLabelText: ---->\(RSQuotesViewController().quoteLabel.text)")// comes back nil
RSQuotesViewController().quoteLabel.text = self.newQuote
}
}
}
}
}
Please let me know if there something I'm missing or an easier/better way of trying to fetch a new quote from the API :)
In your function fetchQuote(), you set quoteVC as a new instantiation of RSQuotesViewController() with let quoteVC = RSQuotesViewController(). Instead you should be setting the quoteLabel.text for the applications instance of RSQuotesViewController(). You are also making two API requests. Once inside the fetchQuote() function for RSQuotesViewController and once inside your fetchQuote() function for RSQuotes
I think what you are looking for would involve closures. Try this out for your fetchQuote() function in your RSQuotes class
func fetchQuote(completion: (result:String)){
let url = "http://ron-swanson-quotes.herokuapp.com/v2/quotes"
Alamofire.request(.GET, url, parameters: nil).responseJSON { response in
if let JSON = response.result.value as? Array<String>{
self.newQuote = JSON[0]
if (self.newQuote.characters.count > 120) {
print("Try Again: ---->\(self.newQuote)")
completion(result: self.newQuote)
} else {
print("Retry was less than 120: ---->\(self.newQuote)")
print("quoteLabelText: ---->\(RSQuotesViewController().quoteLabel.text)")// comes back nil
completion(result: self.newQuote)
}
}
Then, I would have a setQuote function RSQuotesViewController where you could just do something like this
func setQuote() {
let quoteObj = RSQuote()
quoteObj.fetchQuote() {
result in
quoteLabel.text = result
}
}
I would take a look at some posts related to swift closures and also check out. http://goshdarnclosuresyntax.com/
On a side note, I'm not sure if you were planning to manipulate the quoteString within your RSQuote class. If not, it might be better for fetchQuote() to be a static func. This way you can just call it without initializing the object in RSQuoteViewController. It'd be something like RSQuote.fetchQuote()

How to generate random image using image view in swift

I just followed treehouse course and create my first Fun Fact app.In that they generate a random array quotes.
Needed:
I have placed image view using storyboard.Already when pressing one button random array quotes will generate.But i need when that same button pressed a random image should generate.I am new to swift .!
This is factbook.swift
struct FactBook {
// stored in arry to show all quotes
let factsArray = [
"You have to dream before your dreams can come true.",
"To succeed in your mission, you must have single-minded devotion to your goal.",
"You have to dream before your dreams can come true.",
"Love your job but don’t love your company, because you may not know when your company stops loving you.",
"Failure will never overtake me if my definition to succeed is strong enough.",
]
//make a random quote
func randomFact() -> String {
//
// let unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
//
let unsignedArrayCount = UInt32(factsArray.count)
let unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
let randomNumber = Int(unsignedRandomNumber)
//
// let unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
// let randomNumber = Int(signedRandomNumber)
return factsArray[randomNumber]
}
}
This is viewcontroller.swift
class ViewController: UIViewController {
#IBOutlet weak var funFactLabel: UILabel!
#IBOutlet weak var funFactButton: UIButton!
#IBOutlet weak var imgV: UIImageView!
let factBook = FactBook()
let colorWheel = ColorWheel()
//method to define
// let yourImage = UIImage(named: "apj")
// let imageview = UIImageView(image: yourImage)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
funFactLabel.text = factBook.randomFact()
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "apj")!)
// let yourImage = UIImage(named: "apj")
// let imageview = UIImageView(image: yourImage)
// self.view.addSubview(imageview)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func showFunFact() {
let randomColor = colorWheel.randomColor()
view.backgroundColor = randomColor
funFactButton.tintColor = randomColor
//funFactButton.tintColor = clearcolor
funFactLabel.text = factBook.randomFact()
}
}
The solution mainly is to use the same approach you have done with the random text. So to sum up, you should have an array of the images, and a function to select a random image. Then call that function from your view controller. A possible implementation to this approach is:
Add this array to your FactBook
let factsImagesArray = [
"image1.png",
"image2.png",
"image3.png",
"image4.png",
"image5.png",
]
Add this method to your FactBook
func randomFactImage() -> UIImage {
let unsignedArrayCount = UInt32(factsImageArray.count)
let unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
let randomNumber = Int(unsignedRandomNumber)
return UIImage(named: factsImageArray[randomNumber])!
}
and in your viewcontroller change showFunFact to:
#IBAction func showFunFact() {
let randomColor = colorWheel.randomColor()
view.backgroundColor = randomColor
funFactButton.tintColor = randomColor
funFactLabel.text = factBook.randomFact()
imgV.image = faceBook.randomFactImage()
}
Ofc you should have the image1.png, image2.png ... in your resources
#IBAction func randomimage(sender: AnyObject)
{
//list of Images in array
let image : NSArray = [ UIImage(named: "1.jpg")!,
UIImage(named: "2.jpg")!,
UIImage(named: "3.jpg")!,
UIImage(named: "4.jpg")!,
UIImage(named: "5.jpg")!,
UIImage(named: "6.jpg")!,
UIImage(named: "7.jpg")!]
//random image generating method
let imagerange: UInt32 = UInt32(image.count)
let randomimage = Int(arc4random_uniform(imagerange))
let generatedimage: AnyObject = image.objectAtIndex(randomimage)
self.myimage.image = generatedimage as? UIImage
}

Resources