У меня была похожая проблема в приложении, где я полностью контролирую контент. Это не будет работать, если вы загрузите произвольные страницы из Интернета, но оно может работать, если вы знаете свою высокоуровневую структуру DOM, и она не сильно изменится .
Для меня сработало следующее.
Мне пришлось рекурсивно найти первое UIWebView
подпредставление типа UIWebOverflowScrollView
с рамкой (0, 0, 1024, 768)
. Если я не мог найти тот, это был верный признак, что содержание еще не было предоставлено.
Найдя его, я проверяю это представление layer.sublayers.count
. Когда рендеринг заканчивается, я всегда получаю один или три подслоя. Однако, если рендеринг еще не завершен, представление содержимого всегда содержало не более один подслой.
Теперь, , это специфично для моей структуры DOM - но возможно, что вы создадите аналогичный «тест», если вы сравните дерево подслоев до и после рендеринга. Для меня эмпирическое правило было «первое рекурсивно найденное подпредставление типа UIWebOverflowScrollView
будет иметь как минимум три подслоя», для вас оно, скорее всего, будет другим.
В любом случае, будьте очень осторожны, если вы решите использовать этот подход, поскольку, хотя вы не будете отклонены за просмотр представления и иерархии слоев UIWebView
, такое поведение ненадежно и, скорее всего, изменится. в будущих версиях iOS. Это вполне может быть несовместимо между iOS 5 и iOS 6.
Наконец, отрывки кода для MonoTouch, которые должны быть простыми для перевода в Objective C:
bool IsContentScrollView (UIScrollView scrollView)
{
return scrollView.Frame.Equals (new RectangleF (0, 0, 1024, 768));
}
[DllImport ("/usr/lib/libobjc.dylib")]
private static extern IntPtr object_getClassName (IntPtr obj);
public static string GetClassName (this UIView view) {
return Marshal.PtrToStringAuto (object_getClassName (view.Handle));
}
bool IsWebOverflowScrollView (UIScrollView scrollView)
{
return scrollView.GetClassName () == "UIWebOverflowScrollView";
}
IEnumerable<UIScrollView> ScrollViewsInside (UIView view)
{
foreach (var subview in view.Subviews) {
foreach (var scrollView in ScrollViewsInside (subview).ToList())
yield return scrollView;
if (subview is UIScrollView)
yield return (UIScrollView)subview;
}
}
bool CanMakeThumbnail {
get {
var scrollViews = ScrollViewsInside (this).Where (IsWebOverflowScrollView).ToList ();
var contentView = scrollViews.FirstOrDefault (IsContentScrollView);
// I don't know why, but this seems to be a good enough heuristic.
// When the screen is black, either contentView is null or it has just 1 sublayer.
// This may *break* on any iOS updates or DOM changes--be extra careful!
if (contentView == null)
return false;
var contentLayer = contentView.Layer;
if (contentLayer == null || contentLayer.Sublayers == null || contentLayer.Sublayers.Length < 3)
return false;
return true;
}
}