Yogesh Patel
Yogesh Patel

Reputation: 2017

How to Update UISlider Value when Scroll UITableView in Swift 4

When i set the Slider Value see this screenshortenter image description here

And then tableview Scrolling down then the value is changed see this screen short enter image description here

issue is that the value is change when i'm scrolling down i have seen lot's of answers but in Objective-C Please Help me for this in Swift. i am use Xcode 9.2 and Swift 4 Big Thank You !!

Here i will used CoreData but i just want Slider issue !!

class ViewController: UIViewController {

    @IBOutlet var tableView: UITableView!
    var arrData = [String]()
    var studentData = [Student]()
    override func viewDidLoad() {
        super.viewDidLoad()
        studentData = DatabaseHelper.shareInstance.getAllData()
        arrData = [
            "https://is3-ssl.mzstatic.com/image/thumb/Music1/v4/53/58/26/5358265a-e225-2cfb-61da-e6cb68ea5866/source/100x100bb.jpg","https://is3-ssl.mzstatic.com/image/thumb/Music118/v4/3b/cf/4c/3bcf4c0d-a040-3d74-81e9-6ca62c3664ab/source/100x100bb.jpg",
            "https://is2-ssl.mzstatic.com/image/thumb/Music/v4/4f/a6/a3/4fa6a31a-26f0-c025-4f1c-a20da9dd4a32/source/100x100bb.jpg","https://is5-ssl.mzstatic.com/image/thumb/Music5/v4/eb/43/a3/eb43a360-d92e-7dbd-feb8-73b8496ba66f/source/100x100bb.jpg"
        ]
        for arr in arrData{
            DatabaseHelper.shareInstance.save(object: arr)
            self.tableView.reloadData()
        }
    }

}

extension ViewController: UITableViewDelegate, UITableViewDataSource{

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return studentData.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
        cell.studentData = studentData[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 80
    }

// TableViewCell

class TableViewCell: UITableViewCell {


    @IBOutlet var slider: UISlider!
    @IBOutlet var img: UIImageView!
    var studentData:Student!{
        didSet{
            let url = ImageResource(downloadURL: URL(string: studentData.photo!)!, cacheKey: studentData.photo)
            img.kf.setImage(with: url)
            slider.value = studentData.valueslider
        }
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        DatabaseHelper.shareInstance.saveValue(object: slider.value)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }


    @IBAction func sliderBtnClick(_ sender: UISlider) {
        img.alpha = CGFloat(slider.value)
    }


}

//Database Helper

class DatabaseHelper{
    static let shareInstance = DatabaseHelper()

    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    func save(object:String){
        let entity = NSEntityDescription.insertNewObject(forEntityName: "Student", into: context) as! Student
        entity.photo = object
        do{
            try context.save()
        }catch{
            print("Data not save")
        }
    }

    func saveValue(object:Float){
        let entity = NSEntityDescription.insertNewObject(forEntityName: "Student", into: context) as! Student
        entity.valueslider = object
        do{
            try context.save()
        }catch{
            print("Data not save")
        }
    }

    func getAllData() -> [Student]{
        var arrData = [Student]()
        let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Student")
        do{
            arrData = try context.fetch(fetchRequest) as! [Student]
        }catch{
            print("Data not get")
        }
        return arrData
    }
}

Data CoreData Class

import Foundation import CoreData

@objc(Student) public class Student: NSManagedObject {

}

import Foundation
import CoreData

extension Student {

 @nonobjc public class func fetchRequest() -> NSFetchRequest<Student> {
    return NSFetchRequest<Student>(entityName: "Student")
 }

 @NSManaged public var photo: String?
 @NSManaged public var valueslider: Float

}

Upvotes: 1

Views: 1552

Answers (2)

Prince Kumar Sharma
Prince Kumar Sharma

Reputation: 12641

ViewController.swift

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, TableViewCellDelegate {

    @IBOutlet var tableView: UITableView!
    var studentData = [Student]()
    var arrData = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.


        arrData = [
            "https://is3-ssl.mzstatic.com/image/thumb/Music1/v4/53/58/26/5358265a-e225-2cfb-61da-e6cb68ea5866/source/100x100bb.jpg",
            "https://is3-ssl.mzstatic.com/image/thumb/Music118/v4/3b/cf/4c/3bcf4c0d-a040-3d74-81e9-6ca62c3664ab/source/100x100bb.jpg",
            "https://is2-ssl.mzstatic.com/image/thumb/Music/v4/4f/a6/a3/4fa6a31a-26f0-c025-4f1c-a20da9dd4a32/source/100x100bb.jpg",
            "https://is5-ssl.mzstatic.com/image/thumb/Music5/v4/eb/43/a3/eb43a360-d92e-7dbd-feb8-73b8496ba66f/source/100x100bb.jpg"
        ]

        for urlStr in arrData {
            let student = Student(fromPhotoUrl:urlStr);
            studentData.append(student);
        }

        tableView.register(TableViewCell.nib(), forCellReuseIdentifier: TableViewCell.identifier())
        tableView.reloadData();
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return studentData.count
    }

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.identifier(), for: indexPath) as! TableViewCell
        let student = studentData[indexPath.row];
        cell = TableViewCell.configureCell(cell: cell, forStudent: student, atIndex: indexPath.row);
        cell.delegate = self;
        return cell
    }

    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return TableViewCell.height();
    }

    func sliderValueChanged(cell:TableViewCell, sliderChanged changedValue:Float) {
        let student = studentData[cell.tag];
        student.valueslider = changedValue;
        studentData[cell.tag] = student;
    }

}

TableViewCell.swift

import UIKit

class Student {
    var photo: String
    var valueslider:Float = 0.0;
    init(fromPhotoUrl url: String) {
        self.photo = url
    }
}

protocol TableViewCellDelegate: class {
    func sliderValueChanged(cell:TableViewCell, sliderChanged changedValue:Float);
}

class TableViewCell: UITableViewCell {

    var delegate:TableViewCellDelegate? = nil;
    @IBOutlet var slider: UISlider!
    @IBOutlet var img: UIImageView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
    }

    @IBAction func sliderBtnClick(_ sender: UISlider) {
        img.alpha = CGFloat(sender.value);
        self.delegate?.sliderValueChanged(cell: self, sliderChanged: sender.value);
    }

    class func nib() -> UINib {
       return UINib.init(nibName: "TableViewCell", bundle: nil);
    }

    class func identifier() -> String {
        return "TableViewCell";
    }

    class func height() -> CGFloat {
        return CGFloat.init(80);
    }

    class func configureCell(cell:TableViewCell, forStudent student:Student, atIndex index:Int) -> TableViewCell {
        //background task to get data from url
        DispatchQueue.global(qos: .userInitiated).async {
            if let imgUrl = URL(string: student.photo) {
                do {
                    let imageData:Data = try Data(contentsOf: imgUrl as URL)
                    // Bounce back to the main thread to update the UI
                    DispatchQueue.main.async {
                        cell.img.image = UIImage(data: imageData)
                    }
                } catch {
                    print("Unable to load data: \(error)")
                }
            }
        }

        cell.tag = index;
        cell.slider.value = student.valueslider;
        return cell;
    }
}

WORKING-CODE.ZIP

Upvotes: 0

Mansi
Mansi

Reputation: 628

protocol SliderDelegate: class {
    func sliderValueChanged(withValue: Int, cell: TableViewCell)
}

class TableViewCell: UITableViewCell {
    weak var delegate: SliderDelegate?
    @IBAction func sliderBtnClick(_ sender: UISlider) {
       img.alpha = CGFloat(slider.value)
       delegate?.sliderValueChanged(withValue: slider.value, cell: self)  
    }

}

In your View Controller's, table view datasource method

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
        cell.delegate = self
        cell.studentData = studentData[indexPath.row]
        return cell
 }

And conform to Sliderdelegate

extension ViewController: SliderDelegate {
    func sliderValueChanged(withValue: Int, cell: TableViewCell) {
        guard let indexPath = yourTable.indexPath(for: cell) else {
            return
        }
        // Save Slider value to database (Database.save... your logic to update the slider value for the data at this indexPath, goes here) and then reload data like follows
        yourTable.reloadRows(at: [indexPath], with: .none)
}

Upvotes: 2

Related Questions