SkeletonView
SkeletonView copied to clipboard
Does not work in all table cells
Description
Describe your issue here.
What type of issue is this? (place an x
in one of the [ ]
)
- [ ] bug
- [ ] enhancement (feature request)
- [x] question
- [ ] documentation related
- [ ] discussion
Requirements (place an x
in each of the [ ]
)
- [x] I've read and understood the Contributing guidelines and have done my best effort to follow them.
- [x] I've read and agree to the Code of Conduct.
- [x] I've searched for any related issues and avoided creating a duplicate issue.
Bug Report
I have tableView with different cell in different sections
I need create skeletonView like that
But when i use skeletonView on this screen, i get this result
Steps to reproduce:
Please replace this with the steps to reproduce the behavior.
I add dataForUI for skeleton and after create table
override func viewDidLoad() {
super.viewDidLoad()
viewModel.prepareDataForSkeleton()
setUpViews()
}
fileprivate func setUpViews() {
view.addSubview(headerTitle)
headerTitle.labelTitle.text = "Оформление заказа"
headerTitle.snp.makeConstraints { (make) in
make.top.equalTo(0).offset(Utils.shared.screenHeight > 800 ? 60 : 20)
make.left.equalTo(0)
make.right.equalTo(0)
}
headerTitle.layoutIfNeeded()
viewModel.model.titleHeight = Float(headerTitle.labelTitle.frame.height)
view.isSkeletonable = true
view.addSubview(table)
table.delegate = self
table.dataSource = self
table.alwaysBounceVertical = true
table.isScrollEnabled = true
table.contentInsetAdjustmentBehavior = .never
table.estimatedRowHeight = 0
table.rowHeight = UITableView.automaticDimension
table.snp.makeConstraints { (make) in
make.top.equalTo(headerTitle.snp.bottom).offset(-5)
make.bottom.equalTo(0)
make.left.equalTo(0)
make.right.equalTo(0)
}
table.layoutIfNeeded()
}
Code in cell
class OrderAddressTableViewCell: BaseTableViewCell {
public var onTap: (() -> Void)?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.action(_:))))
setUpViews()
contentView.isSkeletonable = true
isSkeletonable = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate let titleLabel: BaseLabel = {
let label = BaseLabel()
label.font = Utils.shared.getFont(Utils.shared.adaptive(16), .bold, .proxima)
label.textColor = Utils.shared.getColor(.black)
label.text = "Адрес и способ доставки"
label.isHidden = true
return label
}()
fileprivate let addressLabel: BaseLabel = {
let label = BaseLabel()
label.font = Utils.shared.getFont(Utils.shared.adaptive(13), .regular, .proxima)
label.textColor = Utils.shared.getColor(.black)
label.letterSpacing = 0.24
label.numberOfLines = 2
label.lineBreakMode = .byWordWrapping
label.lineSpacing = 4
return label
}()
fileprivate let typeDeliveryLabel: BaseLabel = {
let label = BaseLabel()
label.font = Utils.shared.getFont(Utils.shared.adaptive(13), .regular, .proxima)
label.textColor = Utils.shared.getColor(.black)
label.letterSpacing = 0.24
label.numberOfLines = 1
label.lineBreakMode = .byWordWrapping
label.lineSpacing = 4
return label
}()
// MARK: imageViewChevrone
fileprivate var imageViewChevrone: BaseImageView = {
let imageView = BaseImageView()
imageView.image = R.image.category_chevrone()
return imageView
}()
public var skeletonAddressView: BaseView = {
let view = BaseView()
view.isSkeletonable = true
return view
}()
}
extension OrderAddressTableViewCell {
fileprivate func setUpViews() {
contentView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.top.equalTo(0)
make.left.equalTo(16)
make.right.equalTo(-16)
}
contentView.addSubview(addressLabel)
addressLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom).offset(4)
make.left.equalTo(16)
make.right.equalTo(-32)
}
contentView.addSubview(typeDeliveryLabel)
typeDeliveryLabel.snp.makeConstraints { make in
make.top.equalTo(addressLabel.snp.bottom).offset(4)
make.left.equalTo(16)
make.right.equalTo(-16)
make.bottom.equalTo(-11)
}
contentView.addSubview(imageViewChevrone)
imageViewChevrone.snp.makeConstraints { (make) in
make.centerY.equalTo(contentView.snp.centerY)
make.height.equalTo(16)
make.width.equalTo(16)
make.right.equalTo(-16)
}
contentView.addSubview(skeletonAddressView)
skeletonAddressView.snp.makeConstraints { make in
make.left.equalTo(16)
make.right.equalTo(-16)
make.top.bottom.equalTo(0)
}
}
public func initialize(address: String, deliveryType: String) {
addressLabel.text = address
typeDeliveryLabel.text = deliveryType
contentView.hideSkeleton()
hideSkeleton()
titleLabel.isHidden = false
}
public func initializeWithSkeleton() {
let gradient = SkeletonGradient(baseColor: Utils.shared.getColor(.hF9F9F9), secondaryColor: .white)
let animation = SkeletonAnimationBuilder().makeSlidingAnimation(withDirection: .leftRight)
skeletonAddressView.showAnimatedGradientSkeleton(usingGradient: gradient, animation: animation)
}
}
And the same code in every cell, but when I call initializeWithSkeleton in every cell, I have skeleton for only one cell, but if I commented "initializeWithSkeleton" for all cell and leave for one, I have skeleton in this cell
In other screen It's working fine, but on this screen doesn't. I don't why, any help me, pls?
SkeletonView Environment:
SkeletonView version: 1.30.4 Xcode version: Version 14.2 (14C18) Swift version: Swift version 5.7.2
func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? {
let cell = tableView.dequeueReusableCell(withIdentifier: K.surahIdentifier) as? SurahNameCell
guard let cell = cell else { return UITableViewCell() }
cell.someView.isSkeletonable = true
cell.someView.showAnimatedGradientSkeleton()
return cell
}
try this method with SkeletonTableViewDataSource protocol
func collectionSkeletonView(_ skeletonView: UITableView, skeletonCellForRowAt indexPath: IndexPath) -> UITableViewCell? { let cell = tableView.dequeueReusableCell(withIdentifier: K.surahIdentifier) as? SurahNameCell guard let cell = cell else { return UITableViewCell() } cell.someView.isSkeletonable = true cell.someView.showAnimatedGradientSkeleton() return cell }
попробуйте этот метод с протоколом SkeletonTableViewDataSource
Sorry, but it didn't help me
https://github.com/Juanpe/SkeletonView/assets/67915638/a043e3b4-2e9b-4973-99f3-ac32b2d1f97c
I have this result. I don't use hideSkeleton() after finished load.
I use skeleton for special view in cell, in all cell on this screen and painted them so you can see what they are. They are red and green color. When I open screen in first time, I see only one skeleton, but if don't hide skeleton after load, we see other skeleton and if exit from screen and back again we see normal work skeleton. How fix it, can you help me? I hope I wrote clearly
Брат, я прочитал твой текст и посмотрел видео которое ты скинул и ничего не понял. Объясни на русском)
https://github.com/Juanpe/SkeletonView/assets/67915638/618b5d72-5f2d-4efd-93c2-16ce024538de
В общем, проблема такая. Чтобы сделать скелетон, я делаю отдельную модель для таблицы именно для скелетона. После загрузки всей инфы я перезагружаю таблицу использую уже нормальную модель и загружается все остальная информация. На главном экране все работает ок. Если открыть экран с оформлением заказа, то скелетон показывается только для первой ячейки (уточнение: в каждой ячейке я использую отдельно сделанный view специально для скелетона, я их раскрасил еще, чтобы проверить, что они точно есть). И после загрузки всей инфы, показываются остальные скелетоны (хотя должны были быть сразу). НО если перезайти на этот экран, то будет работать нормально, если перезайти еще раз, то еще лучше (на втором видео)
а ты попробовал временно удалить Skeleton? вдруг Skeleton тут не причем
Да, без скелетона норм. Тут же проблема в том, что в остальных ячейках не показывается скелетон, а только в одной. Если я закомментирую скелетоны во всех ячейках кроме одной, то в этой будет показываться, а если включить все обратно, то только в одной
When running multiple loaders simultaneously, make sure they are all called on the main thread. I had this bug, but after wrapping it in the main thread the problem disappeared
DispatchQueue.main.async { view.showAnimatedGradientSkeleton() }
@Juanpe, a call to view.showAnimatedGradientSkeleton()
guarantee that the animation will run on the main thread?
Reference of the answer: https://github.com/Juanpe/SkeletonView/issues/164#issuecomment-543625071