Замена содержимого UIImage(s), загруженного из XIB во время выполнения

Для концепции, которую я разрабатываю, мне нужно загрузить XIB-файлы вручную, и с помощью swizzling методов класса и экземпляра я смог перехватить вызовы imageCustomNamed, imageCustomWithContentsOfFile и imageCustomWithCGImage для класса UIImage и initCustomWithImage для UIImageView. Я хочу определить имя изображения и заменить его некоторым содержимым, отображаемым на лету, вместо того, что установлено в IB во время разработки.

Например:

когда XIB имеет объект UIImageView, для свойства Image которого установлено значение «About.png», мне нужно перехватить загрузку этого изображения и заменить его другим в зависимости от определенных условий. Было бы нормально даже заменить изображение после того, как объект UIImageView загрузил набор изображений во время разработки, но похоже, что исходное имя UIImage, используемое для установки содержимого UIImageView, нигде не хранится.

Я не могу использовать IBOutlets, так как заранее не знаю содержимое файла XIB; это класс, который должен работать на любом XIB, а не только на конкретном.

Пользовательские методы на самом деле вызываются вместо методов по умолчанию, но похоже, что при загрузке XIb система использует imageCustomWithCGImage, которые принимают CGImageRef в качестве аргумента; из него невозможно узнать происхождение (т.е. имя файла изображения)

Любая идея о том, как я могу перехватить загрузку изображений?


person user415080    schedule 09.08.2010    source источник


Ответы (2)


По крайней мере, в OS 3 вы можете переопределить initWithCoder: UIImageNibPlaceholder. Замените его чем-то вроде этого:

-(id)hack_UIImageNibPlaceholder_initWithCoder:(NSCoder*)coder
{
  NSString * name = [coder decodeObjectForKey:@"UIResourceName"];
  [self release];
  return [[UIImage imageNamed:name] retain];
}

Я не уверен, что произойдет, если вы загрузите перья из других пакетов (например, фреймворков).

person tc.    schedule 09.08.2010
comment
Я думал об этом, но это часть личного дела, так что нет-нет. - person user415080; 10.08.2010
comment
Это все личные вещи. Нет никакой гарантии, что вы сможете заменить +[UIImage imageNamed:] и ожидать, что все будет работать после обновления ОС. Иногда это единственный способ. - person tc.; 10.08.2010
comment
Как вы думаете, это не будет обзор? замена +[UIImage imageNamed:] не будет, но это частный API, хотя вы не заменяете какие-либо методы с префиксом подчеркивания - person nbransby; 13.03.2013
comment
@nbransby Из того, что я читал в Интернете, автоматическое обнаружение частного API выполняет только базовый статический анализ, поэтому вы можете пропускать вещи, используя NSClassFromString()/NSSelectorFromString(). Некоторые люди добавляют дополнительную запутанность (например, rot13), но я бы избегал этого: Apple может не возражать против ответственного использования частного API, но это перейдет черту. Как вариант, не используйте перья. - person tc.; 13.03.2013

Возможно, вы можете установить другое свойство UIImageView в файле xib, а затем ссылаться на это свойство? Например, этикетка или тег...

person kolinko    schedule 13.03.2011