Как определить, что UIImageView было задействовано при использовании распознавания жестов? & Rdquo; метод? [Дубликат]

Вы должны поймать исключение до того, как выйдет из лямбда:

s = s.filter(a -> { try { return a.isActive(); } 
                    catch (IOException e) { throw new UncheckedIOException(e); }}});

. Рассмотрите тот факт, что лямбда не оценивается в месте, где вы ее пишете, но при некоторые совершенно несвязанные места, в классе JDK. Таким образом, это будет точка, в которой это исключенное исключение будет выбрано, и в этом месте оно не будет объявлено.

Вы можете справиться с этим, используя обертку вашей лямбды, которая переводит проверенные исключения на непроверенные :

public static <T> T uncheckCall(Callable<T> callable) {
  try { return callable.call(); }
  catch (RuntimeException e) { throw e; }
  catch (Exception e) { throw new RuntimeException(e); }
}

Ваш пример будет написан как

return s.filter(a -> uncheckCall(a::isActive))
        .map(Account::getNumber)
        .collect(toSet());

В моих проектах я рассматриваю этот вопрос без обертывания; вместо этого я использую метод, который эффективно устраняет проверку исключения компилятором. Излишне говорить, что с этим следует обращаться с осторожностью, и все участники проекта должны знать, что проверенное исключение может появиться там, где оно не объявлено. Это код сантехники:

public static <T> T uncheckCall(Callable<T> callable) {
  try { return callable.call(); }
  catch (Exception e) { return sneakyThrow(e); }
}
public static void uncheckRun(RunnableExc r) {
  try { r.run(); } catch (Exception e) { sneakyThrow(e); }
}
public interface RunnableExc { void run() throws Exception; }


@SuppressWarnings("unchecked")
private static <T extends Throwable> void sneakyThrow(Throwable t) throws T {
  throw (T) t;
}

, и вы можете ожидать получить IOException, брошенное вам в лицо, даже если collect не объявляет об этом. В большинстве случаев , но не во всех случаях , которые вы хотели бы просто перестроить исключение, и обрабатывать его как общий сбой. Во всех этих случаях ничто не теряется в ясности или правильности. Просто остерегайтесь тех других случаев, когда вы действительно хотите реагировать на исключение на месте. Разработчик не узнает компилятором, что есть IOException, чтобы поймать там, и компилятор действительно будет жаловаться, если вы попытаетесь его поймать, потому что мы обманули его, полагая, что такое исключение не может быть выброшено.

0
задан Gianfranco Gargano 11 December 2016 в 14:11
поделиться

5 ответов

Если они только белые и черные, было бы намного проще использовать UIView и установить его backgroundColor на .white или .black. Вы можете использовать свойство tag для UIView s, чтобы идентифицировать их.

В вашем обработчике gestureRecognizer recognizer.view сообщает вам view, который вызвал жест.

Вы можете назначить теги в Interface Builder . Например, если у вас есть квадрат квадратов 8x8, вы можете использовать двузначное число, где первая цифра - это строка, а вторая цифра - столбец. Таким образом, ваши теги будут 11, 12, ..., 87, 88.

func squareTapped(recognizer: UIGestureRecognizer) {
    if let view = recognizer.view {
        let tag = view.tag
        let row = tag / 10
        let col = tag % 10
        print("The view at row \(row), column \(col) was tapped")

        if view.backgroundColor == .black {
            view.backgroundColor = .white
        } else {
            view.backgroundColor = .black
        }
    }
}

Если вы хотите использовать изображения, загрузите изображения как свойства вашего viewController и назначить их на основе строки и столбца вашего изображения. Здесь я использовал сборку Outlet Collection , чтобы удерживать все UIImageView s. В Interface Builder вы связываете каждую из своих ячеек с свойством squares.

class BoardViewController: UIViewController {
    let blackImage = UIImage(named: "blackImage")!
    let whiteImage = UIImage(named: "whiteImage")!
    @IBOutlet var squares: [UIImageView]!
    var recognizersAdded = false

    func setUpBoard() {
        for imageview in squares {
            if !recognizersAdded {
                let recognizer = UITapGestureRecognizer(target: self, action: #selector(squareTapped))
                imageview.addGestureRecognizer(recognizer)
                imageview.isUserInteractionEnabled = true
            }

            let tag = view.tag
            let row = tag / 10
            let col = tag % 10

            // Just for demo purposes, set up a checkerboard pattern
            if (row + col) % 2 == 0 {
                imageview.image = blackImage
            } else {
                imageview.image = whiteImage
            }
        }
        recognizersAdded = true
    }

    func squareTapped(recognizer: UIGestureRecognizer) {
        if let view = recognizer.view as? UIImageView {
            let tag = view.tag
            let row = tag / 10
            let col = tag % 10
            print("The view at row \(row), column \(col) was tapped")

            if view.image == blackImage {
                view.image = whiteImage
            } else {
                view.image = blackImage
            } 
        }
    }
}
2
ответ дан vacawama 18 August 2018 в 16:58
поделиться
  • 1
    Моя проблема в том, что если у меня есть два UIImage, мне нужно добавить в Interface Builder два UITapGestureRecognizer, по одному для каждого UIImage, а затем подключить два UITapGestureRecognizer к одному и тому же IBAction. Я новичок в быстром ... вы можете показать, как реализовать свой код в деталях? – Gianfranco Gargano 14 December 2016 в 11:27
  • 2
    Каждому UIImageView нужен собственный UITapGestureRecognizer. Вы можете добавить их программно в процедуру настройки платы. Будьте осторожны, чтобы добавлять их только один раз. Если настройка платы выполняется более одного раза, только первый признак распознается в первый раз. Вы можете контролировать это, имея свойство Bool в вашем VC, которое отслеживает, были ли они добавлены. В Interface Builder подключите каждый из ваших UIImageViews к коллекции IBOutlet квадратов и назначьте теги. – vacawama 14 December 2016 в 11:40
  • 3
    Ошибка новобранец - создать один UITapGestureRecognizer и попытаться добавить это к нескольким представлениям. Это не сработает. Каждое представление нуждается в собственном, поэтому создайте распознаватель внутри цикла установки. – vacawama 14 December 2016 в 11:42
  • 4
    Я обновил код, чтобы показать добавление распознавателей жестов. – vacawama 14 December 2016 в 12:02
  • 5
    Другой вопрос, как вы расположите в матрице форму UIImage? Я использую стек ... – Gianfranco Gargano 14 December 2016 в 15:06

Я добавил добавление PanGestureRecognizer в mainStackView, и я использую эту функцию с hitTest, чтобы узнать, какое представление должно изменить цвет.

func pan(_ recognizer: UIPanGestureRecognizer){
    if (recognizer.state == .began ||
        recognizer.state == .changed)
    {
        let loc = recognizer.location(in: principalRowStack)
        let view = principalRowStack.hitTest(loc, with: UIEvent())
        view?.backgroundColor = .black


    }

}
0
ответ дан Gianfranco Gargano 18 August 2018 в 16:58
поделиться

Присвойте тег каждому типу UIImageView и Add Tap.

После нажатия на любом представлении вы можете получить изображение, которое будет выглядеть:

UIImageView * imageView = gestureRecogniser .view

0
ответ дан sashi_bhushan 18 August 2018 в 16:58
поделиться
0
ответ дан Gianfranco Gargano 7 September 2018 в 01:44
поделиться
0
ответ дан Gianfranco Gargano 30 October 2018 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: