Juanpe / SkeletonView

☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting
MIT License
12.62k stars 1.12k forks source link

Whole Cell is covered animation(Programmatically Solved!!) #283

Closed oguzveozturk closed 4 years ago

oguzveozturk commented 4 years ago

⚠️ Please fill out this template when filing an issue.

🙏🏼 Please check if it already exists other issue related with yours.

What did you do?

Ekran-Resmi-2020-04-01-00-22-24 `import UIKit import SkeletonView

class ViewController: UITableViewController, SkeletonTableViewDataSource {

override func viewDidLoad() {
    super.viewDidLoad()
    view.isSkeletonable = true
    tableView.isSkeletonable = true
    tableView.register(TableViewCell.self, forCellReuseIdentifier: "cell")
    tableView.estimatedRowHeight = 130
  tableView.rowHeight = UITableView.automaticDimension
    view.showAnimatedSkeleton()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    view.updateSkeleton()
}

override func updateViewConstraints() {
    super.updateViewConstraints()
    view.updateSkeleton()
}

func collectionSkeletonView(_ skeletonView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 30
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 30
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
    cell.label.text = "test skeletonView"
    return cell
}

func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier {
    return "cell"
}

}

class TableViewCell: UITableViewCell {

lazy var label: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.text = ""
    label.isSkeletonable = true
    return label
}()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    isSkeletonable = true
    setupLayout()
}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupLayout() {
    addSubview(label)
    NSLayoutConstraint.activate([
        label.centerXAnchor.constraint(equalTo: self.centerXAnchor),
        label.centerYAnchor.constraint(equalTo: self.centerYAnchor),
        label.widthAnchor.constraint(equalToConstant: 300),
        label.heightAnchor.constraint(equalToConstant: 25)
    ])
}

}`

What did you expect to happen?

just want to try skeleton animation in a simple project

What happened instead?

as it shows in the picture; whole cell is covered with animation, not the label inside.

Steps to reproduce the behavior

my code is programmatically written. no storyboard or interface builder. download project.

SkeletonView Environment

SkeletonView version: 1.8.6 Xcode version: 11.4 **Swift version: 5

oguzveozturk commented 4 years ago

Solved issue; when you writing programmatically; view objects should not be added to cell. Should be added to cell's contentView. (as it shows in the pic below) @Juanpe you must add this information to the "How to use" because there are lot of people who encounter the same problem while writing programmatically.

Ekran-Resmi-2020-04-01-17-45-26

boungly commented 3 years ago

Hello @oguzveozturk

I also work on the UI programmatically, and in my case also on UITableViewCell, But I face a problem with the layout during animating as the layout keeps jumping.

UI Structure image

OUTPUT

  • First Load First Load

  • Second ViewDidAppear First ViewDidAppear

  • Other ViewDidAppear Other ViewDidAppear

mendesahdivio commented 1 year ago

hi i tried creating programmatic view as like mentioned above but i dont see any skeleton view for it

import UIKit import SkeletonView

class ViewController: UIViewController { private var viewModel = ViewModel() var strings: [String]?

private let uiTableView: UITableView = { let tableView = UITableView() tableView.translatesAutoresizingMaskIntoConstraints = false tableView.estimatedRowHeight = 100 tableView.rowHeight = 100 tableView.isSkeletonable = true return tableView }()

override func viewDidLoad() { super.viewDidLoad() //set up the tableview uiTableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CellId") setupTableView(uiTableView) setTableViewDelegateAndDataSource(uiTableView)

//call the skeleton view
showAnimationForView()

// call network which is just a simple dispatchqeue with 5 seconds delay
callNetwork()

}

final func setupTableView(_ tableView: UITableView) { view.addSubview(tableView) NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: self.view.topAnchor), tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor) ]) }

final func setTableViewDelegateAndDataSource(_ tableView: UITableView){ tableView.delegate = self tableView.dataSource = self } }

//table view delegate and data source extension ViewController: UITableViewDelegate, SkeletonTableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return strings?.count ?? 10 }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "CellId", for: indexPath) as! CustomTableViewCell if let value = strings?[indexPath.item] { cell.labelView.text = value ?? "boyjdkjfhdsh" cell.uiImageView.image = UIImage(systemName: "heart.fill") } return cell }

func collectionSkeletonView(_ skeletonView: UITableView, cellIdentifierForRowAt indexPath: IndexPath) -> ReusableCellIdentifier { return "CellId" } }

//functions to call skeleton view animations extension ViewController {

private final func showAnimationForView() { view.showAnimatedSkeleton() }

func stopSkeletonView() { self.view.stopSkeletonAnimation() self.view.hideSkeleton() }

func callNetwork() {

DispatchQueue.main.asyncAfter(deadline: .now() + 5) {[weak self] in
  self?.strings =  self?.viewModel.getdata()
  self?.stopSkeletonView()
  self?.uiTableView.reloadData()
}

} }

//dumy view model struct ViewModel { func getdata() -> [String] { return ["hey", "there", "boy", "lol", "test", "make", "proud", "test", "you", "make it worth"] } }

//custom tableview cells with programatic UI class CustomTableViewCell: UITableViewCell {

let labelView: UILabel = { let labelView = UILabel() labelView.font = .systemFont(ofSize: 25) labelView.translatesAutoresizingMaskIntoConstraints = false labelView.numberOfLines = 0 labelView.text = "some randon text" labelView.isSkeletonable = true return labelView }()

let uiImageView: UIImageView = { var imageView = UIImageView() imageView.translatesAutoresizingMaskIntoConstraints = false imageView.image = UIImage() imageView.contentMode = .scaleAspectFit imageView.frame.size.width = 70 imageView.frame.size.height = 70 imageView.clipsToBounds = true imageView.isSkeletonable = true return imageView }()

private lazy var stackView: UIStackView = { let hstack = UIStackView(arrangedSubviews: [ uiImageView, labelView ]) hstack.translatesAutoresizingMaskIntoConstraints = false hstack.axis = .horizontal hstack.spacing = 10 hstack.distribution = .fillEqually hstack.isSkeletonable = true return hstack }()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) isSkeletonable = true contentView.addSubview(stackView) NSLayoutConstraint.activate([ stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0), stackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0), stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0), stackView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0), labelView.widthAnchor.constraint(equalToConstant: 200), labelView.heightAnchor.constraint(equalToConstant: 25) ])

}

required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }