- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
问题描述:
我有一个用于浏览嵌套图像的 iOS 项目 UIScrollViews
其灵感来自著名的 Apple 的 PhotoScroller .
问题是当图像在宽度或高度上缩放时,有时滚动只是“卡住”。这是它在 iPhone 4s
上的外观示例尺寸图片935x1400
高度缩放:
(我开始向左拖动,但 ScrollView 会立即放弃此操作,图像会“卡住”)
解决方法:
通过在缩放后将内部 ScrollView 的内容大小调整为最接近的整数,我找到了一种解决方法:
// Inside ImageScrollView.m
- (void)setZoomScale:(CGFloat)zoomScale
{
[super setZoomScale:zoomScale];
[self fixContentSizeForScrollingIfNecessary];
}
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated
{
[super zoomToRect:rect animated:animated];
[self fixContentSizeForScrollingIfNecessary];
}
- (void)fixContentSizeForScrollingIfNecessary
{
if (SYSTEM_VERSION_LESS_THAN(@"10.2"))
{
CGSize content = self.contentSize;
content.width = rint(content.width);
content.height = rint(content.height);
self.contentSize = content;
}
}
但是这个修复并不完美——现在一些图像的侧面显示有一个像素宽的条纹。例如,在
iPhone 6
尺寸图片
690x14300
它显示在底部:
iOS 7.0 - 10.1
上重现这个问题。 ,但在
iOS 10.2
上一切正常和更大。
最佳答案
无法对帖子发表评论(还没有足够的代表)。
但是从它的外观(Apple 的文档)来看,这个项目 deinits
滚动图像,然后 re-inits
当它们将被加载时(见 UIScrollView.m
中的第 350 行)。而且我还注意到 ImageScrollView.m
里面的评论(第 346 行)明确指出此类旨在避免缓存。这是演示的实用方法,但不适用于生产或实际应用程序,这些应用程序需要像您想要的那样考虑 ui 加载速度。
我还注意到您的应用程序必须进一步滚动才能进行分页。这要么是代码中的一些错误,要么是滞后本身导致主线程无法流畅地运行分页。或者,如果您打算设置如此宽的分页阈值……我建议减少它以获得更好的用户体验,因为现代智能手机的屏幕比 iPhone 4S 的屏幕宽得多。
为了解决这个问题,
我找到了这个 post (波纹管)在 SO 上,它似乎有一个相当不错的 obj-c 方法来缓存,并在应用程序启动后从这样的缓存中获取图像数据。您也应该能够非常简单地将其用于发布后方法,或者甚至将其与网络一起使用以从网络下载图像。您只需要确保您的 UIImage View 正确链接到您使用的 url 字符串,或者通过每个 ImageView 的一组自定义字符串变量,或者通过将 UImageView 子类化为自定义类,并将缓存方法添加到它使您的代码看起来更简单。这是来自 iOSfleer 的帖子中的方法和 NSCahe 类
NSCache 类:
@interface Sample : NSObject
+ (Sample*)sharedInstance;
// set
- (void)cacheImage:(UIImage*)image forKey:(NSString*)key;
// get
- (UIImage*)getCachedImageForKey:(NSString*)key;
@end
#import "Sample.h"
static Sample *sharedInstance;
@interface Sample ()
@property (nonatomic, strong) NSCache *imageCache;
@end
@implementation Sample
+ (Sample*)sharedInstance {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Sample alloc] init];
});
return sharedInstance;
}
- (instancetype)init {
self = [super init];
if (self) {
self.imageCache = [[NSCache alloc] init];
}
return self;
}
- (void)cacheImage:(UIImage*)image forKey:(NSString*)key {
[self.imageCache setObject:image forKey:key];
}
- (UIImage*)getCachedImageForKey:(NSString*)key {
return [self.imageCache objectForKey:key];
}
displayImageWithInfo
ImageScrollview.m 里面的方法改为下面的方法(使用缓存方法),在初始加载后似乎效果更好。如果我是你,我也会更进一步,在 Controller 的
viewDidLoad
中实现一个循环样式的方法。立即缓存这些图像以在启动时更快加载的方法。但这取决于你。
- (void)displayImageWithInfo:(ImageItem*)imageInfo
{
CGSize imageSize = (CGSize){.width = imageInfo.width, .height = imageInfo.height};
// clear the previous imageView
[self.imageView removeFromSuperview];
self.imageView = nil;
// reset our zoomScale to 1.0 before doing any further calculations
self.zoomScale = 1.0;
self.imageView = [[UIImageView alloc] initWithFrame:(CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size = imageSize}];
UIImage *image = [[Sample sharedInstance] getCachedImageForKey:imageInfo.path];
if(image)
{
NSLog(@"This is cached");
((UIImageView*)self.imageView).image = image;
}
else{
NSURL *imageURL = [NSURL URLWithString:imageInfo.path];
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];
if(image)
{
NSLog(@"Caching ....");
[[Sample sharedInstance] cacheImage:image forKey:imageInfo.path];
((UIImageView*)self.imageView).image = image;
}
}
[self addSubview:self.imageView];
[self configureForImageSize:imageSize];
}
ImageView
,只需将其更改为
image
显示 Controller 之后的元素。
Although image objects support all platform-native image formats, it is recommended that you use PNG or JPEG files for most images in your app. Image objects are optimized for reading and displaying both formats, and those formats offer better performance than most other image formats.
viewWillAppear
)之前在其 super View 上添加/初始化的原因。和
viewDidAppear
,或者如果它是在初始加载后完成的,它们很少被取消初始化,它们的内容通常是唯一改变的东西,即使如此,它通常也是异步完成的(如果从网络下载),或者它是从缓存中完成的,它可以也可以使用一些初始化程序自动完成(您可以将其添加到我推荐的内容中):
Use the imageNamed:inBundle:compatibleWithTraitCollection: method (or the imageNamed: method) to create an image from an image asset or image file located in your app’s main bundle (or some other known bundle). Because these methods cache the image data automatically, they are especially recommended for images that you use frequently.
UICollectionViews
的方法。 .值得注意的是,当 View 滚出窗口时,它们具有自动处理内容缓存的委托(delegate)(这正是本演示的内容)。您也可以向这些方法添加自定义代码,以更好地控制这些 View 上的滚动效果。一开始它们可能有点难以理解,但我可以证明,您在此处尝试完成的工作可以使用此演示使用的一小部分代码进行复制。我还认为这个演示是在 2012 年构建的作为一个提示..这是一个非常古老的演示,并且 UICollectionViews 出现在这个演示上次更新时。所以我想说这就是 Apple 一直以来的目标,因为所有面向内容的 UIView 子类无论如何都有某种继承自 UIScrollView
关于ios - 使用嵌套 ScrollView 时滚动获取 "stuck",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44092165/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!