- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 UICollectionViewCell 正在出列以供重用。我最近引入了一个滑动抽屉功能,它基本上是一个隐藏 View ,当用户滑动时会显示出来。
在最后一次更改之后,这似乎会造成实例在初始化时被释放的情况。报告僵尸的确切位置是对“addGestureRecognizers()”的调用,该调用是从 setupSlidingDrawer() 调用的,而 setupSlidingDrawer() 又是从 init 函数调用的。
我附上了僵尸调用前后断点的图像。我整天揪着头发看着这个,却一直一片空白。
作为解决方法(黑客),我将deleteView设置为实例变量,这似乎可以防止类释放,因为保留计数不会减少。
我觉得我的 Collection View 单元/ Controller 的代码非常标准,我没有做任何疯狂的事情。
这似乎是苹果的一个错误,但我似乎无法在互联网上找到任何东西来证明这一点。如果
class MomentsViewCell : UICollectionViewCell, UIGestureRecognizerDelegate {
static let reuseIdentifier = "MomentsViewCell"
let imageView = UIImageView()
let activityIndicator = UIActivityIndicatorView()
let shareButton = UIButton()
var shareCallback: (() -> ())?
var isSwiped = false
let overlayViewTag = 999
var delegate: MomentsViewController?
let shareButtonLength: CGFloat = 44
lazy var drawerWidth: CGFloat = {
self.frame.width * 0.15
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(imageView)
imageView.contentMode = UIViewContentMode.ScaleAspectFit
imageView.snp_makeConstraints { (make) -> Void in
make.centerX.equalTo(self.contentView.snp_centerX)
make.width.equalTo(self.contentView.snp_width)
make.top.equalTo(self.snp_top)
make.bottom.equalTo(self.snp_bottom)
}
contentView.addSubview(activityIndicator)
activityIndicator.hidesWhenStopped = true
activityIndicator.snp_makeConstraints { (make) -> Void in
make.center.equalTo(self.snp_center)
}
let shareImage = UIImage(named: "share-moment")
shareButton.setImage(shareImage, forState: .Normal)
shareButton.addTarget(self, action: "didTapShareButton", forControlEvents: .TouchUpInside)
shareButton.enabled = false
shareButton.alpha = 0.0
imageView.addSubview(shareButton)
imageView.userInteractionEnabled = true
shareButton.snp_makeConstraints { (make) -> Void in
let size = CGSizeMake(shareButtonLength, shareButtonLength)
var offset = shareButtonLength / 2
if let imageLength = shareImage?.size.height {
offset = (shareButtonLength - imageLength) / 2
}
make.bottom.equalTo(self.imageView).multipliedBy(0.95).offset(offset)
make.right.equalTo(self.imageView).multipliedBy(0.95).offset(offset)
make.size.equalTo(size)
}
setupSlidingDrawer()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
exitDeleteMode()
}
func enableSharing() {
shareButton.enabled = true
shareButton.alpha = 1.0
}
func didTapShareButton() {
shareCallback?()
}
func setupSlidingDrawer() {
let deleteView = UIView(frame: CGRectMake(self.frame.width - drawerWidth, self.frame.origin.y, drawerWidth, self.frame.height))
deleteView.backgroundColor = UIColor.whiteColor()
let deleteGradientLayer = CAGradientLayer()
deleteGradientLayer.frame = deleteView.bounds
deleteGradientLayer.colors = [UIColor(hex: 0xE8557C).CGColor, UIColor(hex: 0xCC2B49).CGColor]
deleteView.layer.insertSublayer(deleteGradientLayer, atIndex: 0)
let trashButton = UIButton()
trashButton.setImage(UIImage(named: "trash_can"), forState: UIControlState.Normal)
trashButton.addTarget(self, action: Selector("didPressDelete"), forControlEvents: .TouchUpInside)
deleteView.addSubview(trashButton)
deleteView.bringSubviewToFront(trashButton)
trashButton.snp_makeConstraints(closure: { (make) -> Void in
make.center.equalTo(deleteView.snp_center)
make.width.equalTo(deleteView.snp_width).multipliedBy(0.354)
make.height.equalTo(deleteView.snp_height).multipliedBy(0.07)
})
contentView.addSubview(deleteView)
deleteView.snp_makeConstraints(closure: { (make) -> Void in
make.left.equalTo(self.imageView.snp_right)
make.height.equalTo(self.contentView.snp_height)
make.width.equalTo(drawerWidth)
})
addGestureRecognizers()
}
func addGestureRecognizers() {
let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("didSwipeCell:"))
swipeGestureRecognizer.delegate = self
swipeGestureRecognizer.direction = .Left
self.addGestureRecognizer(swipeGestureRecognizer)
}
class MomentsViewController: ContainerSubController, UICollectionViewDelegate, UICollectionViewDataSource {
var moments: [Moment] = []
let layout = UICollectionViewFlowLayout()
var collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: UICollectionViewFlowLayout())
let headerIdentifier = "headerCellIdentifier"
let headerLabelText = "Moments"
let headerCellHeight: CGFloat = 103.0
let noMomentsLabelText = "It's looking pretty empty in here! Assign a Moments action (Share Moment To Twitter) to a Hot Key to get started."
let noMomentsReuseIdentifier = "NoMoments"
var currentSwipedCellIndexPath: NSIndexPath?
override func viewDidLoad() {
super.viewDidLoad()
layout.minimumLineSpacing = 0
collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout)
collectionView.showsVerticalScrollIndicator = false
collectionView.backgroundColor = UIColor.clearColor()
collectionView.registerClass(MomentsViewCell.self, forCellWithReuseIdentifier: MomentsViewCell.reuseIdentifier)
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: noMomentsReuseIdentifier)
collectionView.registerClass(UICollectionViewCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: headerIdentifier)
collectionView.delegate = self
collectionView.dataSource = self
view.backgroundColor = UIColor.blackColor()
view.addSubview(collectionView)
collectionView.snp_makeConstraints { (make) -> Void in
make.height.equalTo(view)
make.width.equalTo(view)
make.center.equalTo(view)
}
setupTransitionToMainButton()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
refreshMoments()
collectionView.reloadData()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleMomentSavedNotifcation", name: MomentNotifcation.MomentSaved.rawValue, object: nil)
}
//MARK: UICollectionViewDataSource
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
guard let momentsViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(MomentsViewCell.reuseIdentifier, forIndexPath: indexPath) as? MomentsViewCell, moment = moments[safe:indexPath.row] else {
return MomentsViewCell()
}
最佳答案
请注意,确保返回 momentsViewCell
,即您之前出队的那个。
例如:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
if let momentsViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(MomentsViewCell.reuseIdentifier, forIndexPath: indexPath) as? MomentsViewCell {
return momentsViewCell
else {
return MomentsViewCell()
}
编辑
正如我看到的屏幕截图,日志是有关优化的警告。整个赋值可能不起作用,因为稍后不会使用该变量。
关于ios - UICollectionViewCell 消息在出队后立即发送到已释放的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35076277/
我希望在我的应用程序下载信息时显示 Toast 消息,但即使我将它放在我的代码之前,它也不会在下载完成后出现。将我的代码放在一个单独的线程中会引起很多麻烦,但是将 toast 放在一个单独的线程中也不
面临即时应用更新模式的问题。成功完成应用程序更新后,一切都关闭并且不重新启动应用程序。这就是问题所在。 但是android文档说: A full screen user experience that
我有一张 table 我有一个 anchor 标记,
我正在开发一个具有两个线程的 Java/Seam/Hibernate/Glassfish 应用程序: 线程 #1 发送各种消息并将摘要信息写入 MySQL 数据库。 线程 #2 定期轮询数据库(由 S
我找不到规范的相关部分来回答这个问题。在 Java 中的条件运算符语句中,是否同时评估真假参数? 以下是否会抛出 NullPointerException Integer test = null; t
大家下午好, 我想知道是否有办法使类的静态 block 运行,即使类本身没有被引用? 我知道它是延迟加载的,因此只需调用该类的任何函数即可开始启动该类, 但是,我希望该类在任何调用之前启动,换句话说,
我正在尝试使用 jQuery prop() 方法禁用元素(表单字段)。有两个字段,一个叫做fee,一个叫做currency。每当 fee 设置为 0 时,第二个字段 currency 将被禁用。这样做
我想为 UIButton 的缩放设置动画,并在完成后再次为缩放设置动画,但让它在没有动画的情况下旋转。我尝试将旋转变换放在没有持续时间的动画调用中,但不知何故它仍然成为缩放动画的一部分或替换缩放动画。
在 js 代码中,我创建了 3 个按钮 --- 按钮 1...按钮 2...按钮 3和 3 个输入字段 --- 输入字段 1...输入字段 2...输入字段 3 从脚本开始所有按钮都被禁用 只有当输入
我正在使用一个 threading.Thread() 来完成它的工作并返回 。它的返回记录在打印语句中,所以我确信有时候是这样的。然而,依靠 threading.active_count() 和 th
我正在使用 IntelliJ 9,我很好奇是否有任何与 Visual Studio“即时”调试窗口等效的 IntelliJ。在编辑器中选择所需的表达式,然后 ALT-F8 来评估表达式,但我希望能够在
我有一个两个标签页,一个标签是记录列表,点击记录会切换到编辑标签,编辑标签中有保存和取消按钮。 现在,我单击记录 #1,进行一些编辑,然后单击取消按钮。当然我不想验证表单,因为它被取消了,所以我设置了
我有一个 A viewController,首先,我呈现 B viewController,经过一些工作后,我需要关闭 B viewController 并呈现 C viewController,所以
我希望能够在文本框中输入内容,当用户在文本框中输入内容时,我希望程序无需单击按钮即可自动读取文本框。 例子:用户类型:“abcd”当用户输入时,程序会显示每个字母对应的数字。 程序输出:“1234”
如果任何表单输入发生更改,如何立即更改提交按钮文本? //This applies to whole form $('#test').change(function() { $("#send").
主要功能: var interval; function refreshId(sessio
假设我有一个包含这些列的 data.table nodeID hour1aaa hour1bbb hour1ccc hour2aaa hour2bbb hour2ccc .
根据vimeo js-api doc ,事件 finish - 当视频播放结束时触发。 出于某种原因,我无法让它工作,finish 事件总是立即调用,我做错了什么吗? 我试图让嵌入的视频在播放完毕后消
我想滑动当前ul元素下的所有li元素和slideDown li元素 $(document).ready(function(){ $("li").slideUp(); }); $(".nav")
我有一个表-compositeView,其中有行-itemView。每行都有许多事件 - 单击、更改等等。 在某些状态下,我想“锁定”表。禁用按钮并取消事件。 是否有一种好方法可以立即取消 itemv
我是一名优秀的程序员,十分优秀!