13Feb/107
iPhone segédlet 2: érintés feldolgozása, kép mentése
Ez a segédlet az idő hiánya miatt inkább csak felsorolás szintű lesz, viszont az lesz benne, amit a legtöbben kérdeztek eddig:
- képernyő érintésének lekezelése (touchesBegan, touchesMoved, touchesEnded)
- kép lementése a Camera Roll -ba (UIImageWriteToSavedPhotosAlbum, drawRect)
1. A képernyő érintése (A kódot UIViewController-ben kell elhelyezni!)
- Az iPhone (és persze a Touch) készülékek multi touch-osak, ez azt jelenti, hogy egyszerre több érintési pontot is le tudnak kezelni.
Legtöbbször elég csak az első érintéssel foglalkoznunk, most így is fogom bemutatni, viszont a minta kódrészletek alapján egyszerű lesz átírni a multi funkcióra.
- Alapvetően három fontos esemény van, amivel érdemes foglalkozni:
touchesBegan: az érintés kezdete
Ez az esemény akkor következik be, amikor hozzáérünk a kijelzőhöz.
touchesMoved: a képernyőn az ujjunk mozgása
Ez egy folyamatosan frissülő esemény, amikor a képernyőn mozgatjuk az ujjunkat.
(Itt érdemes meggondolni, hogy milyen mintavételezéssel futtatjuk a touchesMoved-ban elhelyezett kódot, illetve hogy minél rövidebb kódot használjunk!)
touchesEnded: az érintés vége
Ez az esemény akkor következik be, ha elengedjük a kijelzőt.
Ha csak egy pillanatra rábökünk a kijelzőre, akkor is a touchesBegan után ez az esemény mindig bekövetkezik!
(Én azt tapasztaltam, hogy ha rá kell kattintani valamire és nem sikerül elsőre eltalálni, akkor az emberek többsége a ujj mozgtásával megkeresik a megfelelő pontot és ott engedik el a kijelzőt, ezért érdemes itt feldolgozni minden olyan eseményt, ami csak egy egyszerű kattintásnak felel meg!)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSSet *allTouches = [event allTouches]; // az összes érintés egy tömbben UITouch *touch = [[allTouches allObjects] objectAtIndex:0]; // az első érintés CGPoint p = [touch locationInView:[self view]]; // az érintés koordinátái NSLog(@"A kezdeti koordináták: %f, %f ", p.x, p.y); }
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSSet *allTouches = [event allTouches]; // az összes érintés egy tömbben UITouch *touch = [[allTouches allObjects] objectAtIndex:0]; // az első érintés CGPoint p = [touch locationInView:[self view]]; // az érintés koordinátái NSLog(@"Mozgás közben az aktuális koordináták: %f, %f ", p.x, p.y); }
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSSet *allTouches = [event allTouches]; // az összes érintés egy tömbben UITouch *touch = [[allTouches allObjects] objectAtIndex:0]; // az első érintés CGPoint p = [touch locationInView:[self view]]; // az érintés koordinátái NSLog(@"Itt engedtem el a kijelzőt: %f, %f ", p.x, p.y); }
2. Kép mentése (A kódot UIView-ban kell elhelyezni!)
- Második AppStore-os programom az iPaint volt, amiben a megrajzolt képet ki lehet menteni a kamera albumba.
A kimetés elég egyszerű, csak arra kell vigyázni, hogy a képet mentés előtt el kell forgatni, mert különben a bitmap fejjel lefelé fog bekerülni az albumba!
Itt egy kicsit átírt kivonat az iPaint-ből, szerintem a kommentek elég beszédesek:
- (void)drawRect:(CGRect)rect { CGFloat _Color[4] = { 255,0,0,1 }; // piros szín CGMutablePathRef path = CGPathCreateMutable(); // ebben a path-ban tároljuk a megjelenítendő vonalakat, pontokat CGContextRef context = UIGraphicsGetCurrentContext(); // az aktuális rajz felület lekérdezése (alap esetben teljes képernyő) // kép elforgatása, hogy a camera roll-ban jó legyen // ezt akkor kell megtenni, ha lementjuk a képet, különben egy if-et tegyünk elé és ne forgassuk, mert a kijelzőn is megfordul! CGContextTranslateCTM(context, 0, self.bounds.size.height); CGContextScaleCTM(context, 1.0, -1.0); // felveszünk egy 3 pixel vastagságú piros vonalat CGContextSetLineWidth(context, 3.0); CGContextSetStrokeColor(context, _Color); CGPathMoveToPoint(path, nil, 5.0, 5.0); CGPathAddLineToPoint(path, nil, 100.0, 100.0); CGContextAddPath(context, path); // kirajzoljuk a képernyőre a path tartalmát (most a piros vonal van benne) CGContextStrokePath(context); // elmentjük a képet UIGraphicsBeginImageContext(self.bounds.size); CGImageRef vImageRef = CGBitmapContextCreateImage(context); CGContextDrawImage(UIGraphicsGetCurrentContext(), self.bounds, vImageRef); UIImage *activeImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // a saveEnded saját függvény, a mentés végén meghívjuk UIImageWriteToSavedPhotosAlbum(activeImage, self, @selector(saveEnded:didFinishSavingWithError: contextInfo:) , nil); CGContextFlush(context); } -(void)saveEnded:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo; { // Ez akkor fut le, ha a mentés véget ért. // Az error-ban megkapjuk, ha valami hiba történt. // Itt érdemes értesíteni a felhasználót, hogy vége a mentésnek és itt érdemes törölni a képernyőt is! }
Legközelebb a Shake, a Status Bar és a levél küldése lesz a téma!
June 30th, 2010 - 07:55
Hello!
Pár napja keresgélek egy egyszerű dologra megoldást.
Van egy UiTextView, aminek a backgroundja egy kép és szeretném eltolni a benne lévő szöveget, gyakorlatilag egy leftmargin beállítás kellene, de sehol sem találok értelmeset, ami nem tolná el a képet is (setcontent). Van erre megoldás ? Nagyon gányolásnak érezném, ha a textView mögé kellene raknom egy képet, ami a háttér lenne, hiszem akkor az nem scrollozódna, nem lenne annyira szép a dolog. Előre is köszönöm a választ.
Ottó
June 30th, 2010 - 11:39
Olyanra gondolsz, mint ami az iTinker tetején van?
Oda egy UIButton-t helyeztem el, és annak a centerjét mozgatom egy NSTimer-rel:
- (void)viewDidLoad {
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(adScroll) userInfo:nil repeats:YES];
}
- (void)adScroll {
adBtn.center = CGPointMake((adBtn.center.x – 5), adBtn.center.y);
if (adBtn.center.x < -90) adBtn.center = CGPointMake(320 + 90, adBtn.center.y);
}
June 30th, 2010 - 12:56
Nem teljesen, adott egy szélességében teljes képet kitöltő UITextView, ebbe iratom ki az adatbázisban lévő adatok egy részét, de megadtam neki egy hátteret, ami elvesz a hasznos területből, bal oldalról körülbelül10 pixelnyit. Ennyivel kellene eltolnom a textViewben lévő szöveget.
Itt a kép az APPról, ( http://m.blog.hu/de/demotivacio/image/radak/helpme.jpg )
Mint látható az a fránya szöveg rámászik a “papír kivágott részére”, ezt szeretném elkerülni anélül, hogy felesleges elemeket kelljen beépíteni.
June 30th, 2010 - 13:04
Esetleg az uitextview.contentInset = UIEdgeInsetsMake(10,0,0,0); ?
June 30th, 2010 - 14:14
Próbáltam, de egyik paraméterrel sem tolta el a megfelelő tengelyen. Valamiért csak az Y tegnelyen mozdult el a szöveg. contentInset-et ezután próbáltam Builderből állítani akkor viszont magát a képet is nyújtotta, viszont lehet +10-el paramétereztem hibásan, ha hazaérek ezt újra megpróbálom, mert ez volt az egyetlen megoldás amivel ténylegesen csak a szöveget sikerült befolyásolnom, viszont mint mondtam valamiért csak függőleges eltolást tudtam kicsikarni.
June 30th, 2010 - 14:23
*tengelyen
July 2nd, 2010 - 09:12
Sajnos jól csináltam múltkor is, ez csak függőlegesen tolja lejjebb a szöveget, a margint el tudja tűntetni a negatív paraméterezése, de semmilyen paraméterrel sem tudom megtoldani.
self.textView.contentInset = UIEdgeInsetsMake(100,0,0,0);
pl letolja nekem a szöveget 100 pixellel.