如果没有图像,收缩collectionViewCell的高度

时间:2017-07-02 10:30:01

标签: ios swift uicollectionview uicollectionviewcell

我有一个单元格,图像固定在单元格的左上角。与图像有关的其他限制。

enter image description here

这是图像高度约束:

enter image description here

这是我的数据设置器:

import React, { Component } from 'react'
import { Text, View, Image, StyleSheet, Dimensions } from 'react-native'
import { Content, Container } from 'native-base'
import Carousel from 'react-native-looped-carousel'

const {width, height} = Dimensions.get('window')
export default class AppBody extends Component {

  constructor(props) {
    super(props)

    this.state = {
      size: {width, height},
    }
  }

  render() {
    return (
      <Container>
        <Content>
          <Carousel
            delay={2000}
            style={this.state.size}
            autoplay
            pageInfo
            onAnimateNextPage={(p) => console.log(p)}
          >
            <View style={[{backgroundColor: '#BADA55'}, this.state.size]}><Text>1</Text></View>
            <View style={[{backgroundColor: 'red'}, this.state.size]}><Text>2</Text></View>
            <View style={[{backgroundColor: 'blue'}, this.state.size]}><Text>3</Text></View>
          </Carousel>
        </Content>
      </Container>
    )
  }
}

module.export = AppBody

我使用KingFisher库通过REST Api从后端获取图像。

问题是一些细胞有图像,然后一切正常,但有些细胞没有图像,然后出现空白空间。

enter image description here

如果没有图像和缩小单元格高度以适合内容,我想隐藏空白区域。我怎么能这样做?

解决: 这是我如何在@ 方明宁

的帮助下解决它

我为图片高度添加了一个插座:

import UIKit import Kingfisher class WorkoutSectionCollectionViewCell: UICollectionViewCell { @IBOutlet weak var colorLine: UIView! @IBOutlet weak var workoutName: UILabel! @IBOutlet weak var widthConstraint: NSLayoutConstraint! @IBOutlet weak var workoutDescription: UILabel! @IBOutlet weak var parametersStackView: UIStackView! @IBOutlet weak var exercisesIcon: UIImageView! @IBOutlet weak var exercisesLabel: UILabel! @IBOutlet weak var musclesIcon: UIImageView! @IBOutlet weak var musclesLabel: UILabel! @IBOutlet weak var workoutImage: UIImageView! var workout: Workout? { didSet { // Get image form backend if let imageUrl = workout?.workoutImage?.imageUrl { let resource = ImageResource(downloadURL: URL(string: imageUrl)!, cacheKey: imageUrl) workoutImage.kf.setImage(with: resource) workoutImage.isHidden = false } else { workoutImage.isHidden = true } if let workoutKind = workout?.workoutKind { switch workoutKind { case "силовая": colorLine.backgroundColor = Colors.colorCadmiumOrange case "фитнес": colorLine.backgroundColor = Colors.colorGreen case "кардио": colorLine.backgroundColor = Colors.colorBlueDeFrance case "HIIT": colorLine.backgroundColor = Colors.colorCarminePink default: colorLine.backgroundColor = Colors.colorClear } } workoutName.text = workout?.workoutName if let workoutDesc = workout?.workoutDesc { workoutDescription.text = workoutDesc.html2String } if let numberOfExercises = workout?.workoutExercises?.count { exercisesLabel.text = "\(numberOfExercises) " + pluralForm(number: numberOfExercises, forms: ["упражнение", "упражнения", "упражнений"]) } var workoutMuscles: [String] = [] workout?.workoutExercises?.forEach({ (exercise) in workoutMuscles.append((exercise as! Exercise).mainMuscle!) }) musclesLabel.text = Set(workoutMuscles).joined(separator: ", ").lowercased() } } override func awakeFromNib() { super.awakeFromNib() // Initialization code self.contentView.translatesAutoresizingMaskIntoConstraints = false let screenWidth = UIScreen.main.bounds.size.width widthConstraint.constant = screenWidth - 20 self.layer.cornerRadius = 3 workoutName.textColor = Colors.colorPaynesGrey workoutDescription.textColor = Colors.colorDimGray exercisesLabel.textColor = Colors.colorSilver musclesLabel.textColor = Colors.colorSilver musclesIcon.tintColor = Colors.colorSilver exercisesIcon.tintColor = Colors.colorSilver }

然后设置窗口宽度和插入(左和右10):

@IBOutlet weak var imageHeightConstraint: NSLayoutConstraint!

在didSet中添加以下代码:

let screenWidth = UIScreen.main.bounds.size.width
let screenInsets: CGFloat = 20

在IB中,图像约束看起来像这样: enter image description here

2 个答案:

答案 0 :(得分:1)

如果您的图像来自异步服务器调用,那么在回调中没有图像时缩小单元格并不是一个好主意。如果你这样做,你的表视图会出现很多问题,用户体验会很糟糕。

相反,在您首先检索文本的调用中,您需要检查是否有图像。然后,隐藏第一个地方的图像视图,而不是先放置空格,然后检查图像是否存在。

为此,在您的服务器调用中,假设您在返回的JSON响应中包含一个键 hasImage 。我们还需要设置单元格,以便顶部的图像视图具有高度约束。底部的文本视图需要有约束说填充顶部。这样,当您将图像视图高度设置为0时,文本视图将自动向上移动收缩一个单元格。

首先,给你的高度约束一个标识符,以便我们可以从代码中更改它。看起来像这样

enter image description here

现在,在您的cellForRow中,您可以执行类似

的操作
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "ImageCell") as! ImageCell
    if dataArray[indexPath.row].hasImage {
        //add image
    } else {
        let filteredConstraints = cell.imgView.constraints.filter { $0.identifier == "imgTxtCellImgHeight" }
        if let heightConstraint = filteredConstraints.first {
            heightConstraint.constant = 0
        }
    }
    return cell
}

答案 1 :(得分:0)

在您的单元格类中输出您的workoutImage高度约束

@IBOutlet weak var workoutImageHeight: NSLayoutConstraint!

并在你的didSet中: -

didSet {
        // Get image form backend
        if let imageUrl = workout?.workoutImage?.imageUrl {
            let resource = ImageResource(downloadURL: URL(string: imageUrl)!, cacheKey: imageUrl)
            workoutImage.kf.setImage(with: resource)
            workoutImageHeight.constant = 200 // make this value as you want
        } else {
            workoutImageHeight.constant = 0
        }
}

并将此UICOllectionViewDelegateFlowLayout方法添加到您的控制器

func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout, 
               sizeForItemAt indexPath: IndexPath) -> CGSize{
      // replace the name of workoutArray from your array..
      if let imageUrl = workoutArray[indexPath.item]?.workoutImage?.imageUrl {              
           // replace height as you want  
           return CGSize(width:collectionView.bounds.width , height:400)
        } else {
           return CGSize(width:collectionView.bounds.width , height:200) 
        }
}